Support for lowering references to imported vars. (#5513)

Previously we walked the global variables defined by the current file
and emitted an LLVM global variable definition for each of them. Now
instead, when emitting a constant reference to a global variable, we
emit an LLVM global variable declaration, and we then subsequently walk
the global variables defined by the current file and convert each of
them from a declaration to a definition.

In order to make import of names of global variables work, add support
for import of `var`, as well as support for importing `tuple_access` and
`tuple_pattern` in the case where the `var` has a tuple pattern in its
declaration. Also treat `bind_name`s that are reference bindings to
`var`s as having the same constant reference value as their `var` so
that we can properly import and lower them.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
This commit is contained in:
Richard Smith
2025-05-29 19:48:16 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins Carbon Infra Bot
parent c6f25e9018
commit a23631f360
174 changed files with 1279 additions and 749 deletions
@@ -63,7 +63,7 @@ fn F(n: i32, a: array(i32, n)*);
// CHECK:STDOUT: %n.ref: %i32 = name_ref n, %n
// CHECK:STDOUT: %ptr: type = ptr_type <error> [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: <error> = bind_name a, %a.param
// CHECK:STDOUT: %a: <error> = bind_name a, %a.param [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
+25 -25
View File
@@ -548,7 +548,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc6_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc6_9.3: type = converted %.loc6_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var [concrete = %a.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.7ce = binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.7ce = var_pattern %b.patt [concrete]
@@ -558,7 +558,7 @@ import library "extern_api";
// CHECK:STDOUT: %int_32.loc7: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32.loc7: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var [concrete = %b.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.688 = binding_pattern c [concrete]
// CHECK:STDOUT: %c.var_patt: %pattern_type.688 = var_pattern %c.patt [concrete]
@@ -569,7 +569,7 @@ import library "extern_api";
// CHECK:STDOUT: %i32.loc8: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var [concrete = %c.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.cb1 = binding_pattern d [concrete]
// CHECK:STDOUT: %d.var_patt: %pattern_type.cb1 = var_pattern %d.patt [concrete]
@@ -579,7 +579,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc9_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc9_9.3: type = converted %.loc9_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var [concrete = %d.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %e.patt: %pattern_type.cb1 = binding_pattern e [concrete]
// CHECK:STDOUT: %e.var_patt: %pattern_type.cb1 = var_pattern %e.patt [concrete]
@@ -589,7 +589,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc10_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc10_9.3: type = converted %.loc10_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var [concrete = %e.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @A [from "api.carbon"];
@@ -759,7 +759,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc52_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc52_9.3: type = converted %.loc52_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var [concrete = %a.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.7ce = binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.7ce = var_pattern %b.patt [concrete]
@@ -769,7 +769,7 @@ import library "extern_api";
// CHECK:STDOUT: %int_32.loc53: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32.loc53: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var [concrete = %b.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.688 = binding_pattern c [concrete]
// CHECK:STDOUT: %c.var_patt: %pattern_type.688 = var_pattern %c.patt [concrete]
@@ -780,7 +780,7 @@ import library "extern_api";
// CHECK:STDOUT: %i32.loc54: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var [concrete = %c.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.cb1 = binding_pattern d [concrete]
// CHECK:STDOUT: %d.var_patt: %pattern_type.cb1 = var_pattern %d.patt [concrete]
@@ -790,7 +790,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc55_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc55_9.3: type = converted %.loc55_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var [concrete = %d.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %e.patt: %pattern_type.cb1 = binding_pattern e [concrete]
// CHECK:STDOUT: %e.var_patt: %pattern_type.cb1 = var_pattern %e.patt [concrete]
@@ -800,7 +800,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc56_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc56_9.3: type = converted %.loc56_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var [concrete = %e.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @A [from "api.carbon"];
@@ -970,7 +970,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc12_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc12_9.3: type = converted %.loc12_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var [concrete = %a.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.501 = binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.501 = var_pattern %b.patt [concrete]
@@ -980,7 +980,7 @@ import library "extern_api";
// CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32.loc13: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var [concrete = %b.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.f5f = binding_pattern c [concrete]
// CHECK:STDOUT: %c.var_patt: %pattern_type.f5f = var_pattern %c.patt [concrete]
@@ -991,7 +991,7 @@ import library "extern_api";
// CHECK:STDOUT: %i32.loc14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var [concrete = %c.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.cb1 = binding_pattern d [concrete]
// CHECK:STDOUT: %d.var_patt: %pattern_type.cb1 = var_pattern %d.patt [concrete]
@@ -1001,7 +1001,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc15_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc15_9.3: type = converted %.loc15_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var [concrete = %d.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %e.patt: %pattern_type.cb1 = binding_pattern e [concrete]
// CHECK:STDOUT: %e.var_patt: %pattern_type.cb1 = var_pattern %e.patt [concrete]
@@ -1011,7 +1011,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc16_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc16_9.3: type = converted %.loc16_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var [concrete = %e.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @A;
@@ -1155,7 +1155,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc52_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc52_9.3: type = converted %.loc52_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var [concrete = %a.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.7ce = binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.7ce = var_pattern %b.patt [concrete]
@@ -1165,7 +1165,7 @@ import library "extern_api";
// CHECK:STDOUT: %int_32.loc53: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32.loc53: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var [concrete = %b.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.688 = binding_pattern c [concrete]
// CHECK:STDOUT: %c.var_patt: %pattern_type.688 = var_pattern %c.patt [concrete]
@@ -1176,7 +1176,7 @@ import library "extern_api";
// CHECK:STDOUT: %i32.loc54: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var [concrete = %c.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.cb1 = binding_pattern d [concrete]
// CHECK:STDOUT: %d.var_patt: %pattern_type.cb1 = var_pattern %d.patt [concrete]
@@ -1186,7 +1186,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc55_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc55_9.3: type = converted %.loc55_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var [concrete = %d.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %e.patt: %pattern_type.cb1 = binding_pattern e [concrete]
// CHECK:STDOUT: %e.var_patt: %pattern_type.cb1 = var_pattern %e.patt [concrete]
@@ -1196,7 +1196,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc56_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc56_9.3: type = converted %.loc56_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var [concrete = %e.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @A [from "api.carbon"];
@@ -1340,7 +1340,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc52_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc52_9.3: type = converted %.loc52_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var
// CHECK:STDOUT: %a: ref %empty_tuple.type = bind_name a, %a.var [concrete = %a.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.7ce = binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.7ce = var_pattern %b.patt [concrete]
@@ -1350,7 +1350,7 @@ import library "extern_api";
// CHECK:STDOUT: %int_32.loc53: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32.loc53: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var
// CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var [concrete = %b.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.688 = binding_pattern c [concrete]
// CHECK:STDOUT: %c.var_patt: %pattern_type.688 = var_pattern %c.patt [concrete]
@@ -1361,7 +1361,7 @@ import library "extern_api";
// CHECK:STDOUT: %i32.loc54: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var
// CHECK:STDOUT: %c: ref %struct_type.c = bind_name c, %c.var [concrete = %c.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.cb1 = binding_pattern d [concrete]
// CHECK:STDOUT: %d.var_patt: %pattern_type.cb1 = var_pattern %d.patt [concrete]
@@ -1371,7 +1371,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc55_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc55_9.3: type = converted %.loc55_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var
// CHECK:STDOUT: %d: ref %empty_tuple.type = bind_name d, %d.var [concrete = %d.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %e.patt: %pattern_type.cb1 = binding_pattern e [concrete]
// CHECK:STDOUT: %e.var_patt: %pattern_type.cb1 = var_pattern %e.patt [concrete]
@@ -1381,7 +1381,7 @@ import library "extern_api";
// CHECK:STDOUT: %.loc56_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc56_9.3: type = converted %.loc56_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var
// CHECK:STDOUT: %e: ref %empty_tuple.type = bind_name e, %e.var [concrete = %e.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @A;
@@ -106,7 +106,7 @@ var f: () = F();
// CHECK:STDOUT: %.loc6_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc6_9.3: type = converted %.loc6_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f: ref %empty_tuple.type = bind_name f, %f.var
// CHECK:STDOUT: %f: ref %empty_tuple.type = bind_name f, %f.var [concrete = %f.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F [from "export.carbon"];
@@ -128,7 +128,7 @@ extern library "basic" fn F();
// CHECK:STDOUT: %.loc4_9.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc4_9.3: type = converted %.loc4_9.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: ref %empty_tuple.type = bind_name x, %x.var
// CHECK:STDOUT: %x: ref %empty_tuple.type = bind_name x, %x.var [concrete = %x.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: extern fn @F [from "basic.carbon"];