Provide the callee expression to the Call node. (#3291)

Track the callee expression in full, instead of only tracking the
callee's FunctionId. This results in the `name_reference` denoting the
function actually being used.

Lowering now propagates a `llvm::Function*` as the value associated with
expressions of type `<function>`.

We were not creating `NameReference` node for names produced by member
access into a namespace, such as the second name in
`Namespace.Function`, which caused lowering of calls to such names to
fail. This is now fixed, but the resulting `NameReference` node only
refers to the name and the lookup result, not to the `Namespace.`
qualifier. We'll need to decide how to fit a third operand into that
node (perhaps we can stop storing the `name_id`, since it can be derived
from the lookup result) but for now the qualifier is not tracked.
This commit is contained in:
Richard Smith
2023-10-13 22:06:23 +00:00
committed by GitHub
parent c61b6a0e1d
commit 1ae5fe0cd5
43 changed files with 110 additions and 101 deletions
+2 -2
View File
@@ -42,8 +42,8 @@ static auto FindReturnSlotForInitializer(SemIR::File& semantics_ir,
case SemIR::Call::Kind: {
auto call = init.As<SemIR::Call>();
if (!semantics_ir.GetFunction(call.function_id)
.return_slot_id.is_valid()) {
if (!SemIR::GetInitializingRepresentation(semantics_ir, call.type_id)
.has_return_slot()) {
return SemIR::NodeId::Invalid;
}
return semantics_ir.GetNodeBlock(call.args_id).back();
+7 -7
View File
@@ -14,16 +14,16 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool {
context.ParamOrArgEndNoPop(Parse::NodeKind::CallExpressionStart);
// TODO: Convert to call expression.
auto [call_expr_parse_node, name_id] =
auto [call_expr_parse_node, callee_id] =
context.node_stack()
.PopWithParseNode<Parse::NodeKind::CallExpressionStart>();
auto name_node =
context.semantics_ir().GetNode(context.FollowNameReferences(name_id));
auto function_name = name_node.TryAs<SemIR::FunctionDeclaration>();
auto callee_node =
context.semantics_ir().GetNode(context.FollowNameReferences(callee_id));
auto function_name = callee_node.TryAs<SemIR::FunctionDeclaration>();
if (!function_name) {
// TODO: Work on error.
context.TODO(parse_node, "Not a callable name");
context.node_stack().Push(parse_node, name_id);
context.node_stack().Push(parse_node, callee_id);
context.ParamOrArgPop();
return true;
}
@@ -50,14 +50,14 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool {
// Convert the arguments to match the parameters.
auto refs_id = context.ParamOrArgPop();
if (!ConvertCallArgs(context, call_expr_parse_node, refs_id,
name_node.parse_node(), callable.param_refs_id,
callee_node.parse_node(), callable.param_refs_id,
callable.return_slot_id.is_valid())) {
context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError);
return true;
}
auto call_node_id = context.AddNode(
SemIR::Call(call_expr_parse_node, type_id, refs_id, function_id));
SemIR::Call(call_expr_parse_node, type_id, callee_id, refs_id));
context.node_stack().Push(parse_node, call_node_id);
return true;
+5 -1
View File
@@ -22,7 +22,11 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node)
auto node_id =
context.LookupName(parse_node, name_id, namespc->name_scope_id,
/*print_diagnostics=*/true);
context.node_stack().Push(parse_node, node_id);
auto node = context.semantics_ir().GetNode(node_id);
// TODO: Track that this node was named within `base_id`.
context.AddNodeAndPush(
parse_node,
SemIR::NameReference(parse_node, node.type_id(), name_id, node_id));
return true;
}
+2 -2
View File
@@ -28,13 +28,13 @@ fn G() {
// CHECK:STDOUT: %.loc10_42.1: i32 = int_literal 0
// CHECK:STDOUT: %.loc10_42.2: ref (i32, i32, i32) = array_index %v, %.loc10_42.1
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc10_35: init (i32, i32, i32) = call @F() to %.loc10_42.3
// CHECK:STDOUT: %.loc10_35: init (i32, i32, i32) = call %F.ref.loc10_34() to %.loc10_42.3
// CHECK:STDOUT: %F.ref.loc10_39: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_42.6: ref (i32, i32, i32) = splice_block %.loc10_42.5 {
// CHECK:STDOUT: %.loc10_42.4: i32 = int_literal 1
// CHECK:STDOUT: %.loc10_42.5: ref (i32, i32, i32) = array_index %v, %.loc10_42.4
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc10_40: init (i32, i32, i32) = call @F() to %.loc10_42.6
// CHECK:STDOUT: %.loc10_40: init (i32, i32, i32) = call %F.ref.loc10_39() to %.loc10_42.6
// CHECK:STDOUT: %.loc10_42.7: type = tuple_type ((i32, i32, i32), (i32, i32, i32))
// CHECK:STDOUT: %.loc10_42.8: ((i32, i32, i32), (i32, i32, i32)) = tuple_literal (%.loc10_35, %.loc10_40)
// CHECK:STDOUT: %.loc10_42.9: init [(i32, i32, i32); 2] = array_init %.loc10_42.8, (%.loc10_35, %.loc10_40) to %v
+1 -1
View File
@@ -29,7 +29,7 @@ fn Run() {
// CHECK:STDOUT: %.loc10_17: type = array_type %.loc10_16, i32
// CHECK:STDOUT: %t: ref [i32; 1] = var "t"
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_22.1: init (i32,) = call @F()
// CHECK:STDOUT: %.loc10_22.1: init (i32,) = call %F.ref()
// CHECK:STDOUT: %.loc10_22.2: ref (i32,) = temporary_storage
// CHECK:STDOUT: %.loc10_22.3: ref (i32,) = temporary %.loc10_22.2, %.loc10_22.1
// CHECK:STDOUT: %.loc10_22.4: ref i32 = tuple_access %.loc10_22.3, member0
+1 -1
View File
@@ -49,7 +49,7 @@ fn G() -> i32 {
// CHECK:STDOUT: %.loc12_20.13: init [i32; 3] = array_init %.loc12_20.2, (%.loc12_20.6, %.loc12_20.9, %.loc12_20.12) to %.loc12_20.3
// CHECK:STDOUT: %.loc12_20.14: ref [i32; 3] = temporary %.loc12_20.3, %.loc12_20.13
// CHECK:STDOUT: %.loc12_20.15: [i32; 3] = bind_value %.loc12_20.14
// CHECK:STDOUT: %.loc12_11.1: init i32 = call @F(%.loc12_20.15, %.loc12_23)
// CHECK:STDOUT: %.loc12_11.1: init i32 = call %F.ref(%.loc12_20.15, %.loc12_23)
// CHECK:STDOUT: %.loc12_11.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc12_11.3: ref i32 = temporary %.loc12_11.2, %.loc12_11.1
// CHECK:STDOUT: %.loc12_11.4: i32 = bind_value %.loc12_11.3
@@ -30,16 +30,16 @@ fn H() -> i32 {
// CHECK:STDOUT: %v: ref (i32, i32) = var "v"
// CHECK:STDOUT: %F.ref.loc10: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_7: ref (i32, i32) = splice_block %v {}
// CHECK:STDOUT: %.loc10_24: init (i32, i32) = call @F() to %.loc10_7
// CHECK:STDOUT: %.loc10_24: init (i32, i32) = call %F.ref.loc10() to %.loc10_7
// CHECK:STDOUT: assign %v, %.loc10_24
// CHECK:STDOUT: %v.ref: ref (i32, i32) = name_reference "v", %v
// CHECK:STDOUT: %F.ref.loc11: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc11_3: ref (i32, i32) = splice_block %v.ref {}
// CHECK:STDOUT: %.loc11_8: init (i32, i32) = call @F() to %.loc11_3
// CHECK:STDOUT: %.loc11_8: init (i32, i32) = call %F.ref.loc11() to %.loc11_3
// CHECK:STDOUT: assign %v.ref, %.loc11_8
// CHECK:STDOUT: %F.ref.loc12: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc9: ref (i32, i32) = splice_block %return {}
// CHECK:STDOUT: %.loc12: init (i32, i32) = call @F() to %.loc9
// CHECK:STDOUT: %.loc12: init (i32, i32) = call %F.ref.loc12() to %.loc9
// CHECK:STDOUT: return %.loc12
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -47,7 +47,7 @@ fn H() -> i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc16_11.1: ref (i32, i32) = temporary_storage
// CHECK:STDOUT: %.loc16_11.2: init (i32, i32) = call @G() to %.loc16_11.1
// CHECK:STDOUT: %.loc16_11.2: init (i32, i32) = call %G.ref() to %.loc16_11.1
// CHECK:STDOUT: %.loc16_14: i32 = int_literal 0
// CHECK:STDOUT: %.loc16_11.3: ref (i32, i32) = temporary %.loc16_11.1, %.loc16_11.2
// CHECK:STDOUT: %.loc16_15.1: ref i32 = tuple_index %.loc16_11.3, %.loc16_14
+1 -1
View File
@@ -28,6 +28,6 @@ fn Main() {
// CHECK:STDOUT: %Echo.ref: <function> = name_reference "Echo", package.%Echo
// CHECK:STDOUT: %.loc12_9.1: {} = struct_literal ()
// CHECK:STDOUT: %.loc12_9.2: {} = struct_value %.loc12_9.1, ()
// CHECK:STDOUT: %.loc12_7: init {} = call @Echo(%.loc12_9.2)
// CHECK:STDOUT: %.loc12_7: init {} = call %Echo.ref(%.loc12_9.2)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -28,6 +28,6 @@ fn Main() {
// CHECK:STDOUT: %Echo.ref: <function> = name_reference "Echo", package.%Echo
// CHECK:STDOUT: %.loc12_9.1: () = tuple_literal ()
// CHECK:STDOUT: %.loc12_9.2: () = tuple_value %.loc12_9.1, ()
// CHECK:STDOUT: %.loc12_7: init () = call @Echo(%.loc12_9.2)
// CHECK:STDOUT: %.loc12_7: init () = call %Echo.ref(%.loc12_9.2)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -28,7 +28,7 @@ fn Run() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x: ref i32 = var "x"
// CHECK:STDOUT: %Foo.ref: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc13: init f64 = call @Foo()
// CHECK:STDOUT: %.loc13: init f64 = call %Foo.ref()
// CHECK:STDOUT: assign %x, <error>
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -28,7 +28,7 @@ fn Main() {
// CHECK:STDOUT: %b: ref i32 = var "b"
// CHECK:STDOUT: %Echo.ref: <function> = name_reference "Echo", package.%Echo
// CHECK:STDOUT: %.loc12_21: i32 = int_literal 1
// CHECK:STDOUT: %.loc12_20: init i32 = call @Echo(%.loc12_21)
// CHECK:STDOUT: %.loc12_20: init i32 = call %Echo.ref(%.loc12_21)
// CHECK:STDOUT: assign %b, %.loc12_20
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -34,6 +34,6 @@ fn Main() {
// CHECK:STDOUT: %.loc11_20: i32 = add %.loc11_18, %.loc11_22
// CHECK:STDOUT: %.loc11_25: i32 = int_literal 6
// CHECK:STDOUT: %.loc11_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc11_6.2: init () = call @Foo(%.loc11_13, %.loc11_20, %.loc11_25)
// CHECK:STDOUT: %.loc11_6.2: init () = call %Foo.ref(%.loc11_13, %.loc11_20, %.loc11_25)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -25,6 +25,6 @@ fn Main() {
// CHECK:STDOUT: %Foo.ref: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc10_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc10_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc10_6.2: init () = call @Foo(%.loc10_7)
// CHECK:STDOUT: %.loc10_6.2: init () = call %Foo.ref(%.loc10_7)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -26,9 +26,9 @@ fn Main() {
// CHECK:STDOUT: %Foo.ref.loc10: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc10_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc10_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc10_6.2: init () = call @Foo(%.loc10_7)
// CHECK:STDOUT: %.loc10_6.2: init () = call %Foo.ref.loc10(%.loc10_7)
// CHECK:STDOUT: %Foo.ref.loc11: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc11_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc11_6: init () = call @Foo(%.loc11_7)
// CHECK:STDOUT: %.loc11_6: init () = call %Foo.ref.loc11(%.loc11_7)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -26,6 +26,6 @@ fn Main() {
// CHECK:STDOUT: %.loc10_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc10_10: i32 = int_literal 2
// CHECK:STDOUT: %.loc10_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc10_6.2: init () = call @Foo(%.loc10_7, %.loc10_10)
// CHECK:STDOUT: %.loc10_6.2: init () = call %Foo.ref(%.loc10_7, %.loc10_10)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -27,10 +27,10 @@ fn Main() {
// CHECK:STDOUT: %.loc10_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc10_10: i32 = int_literal 2
// CHECK:STDOUT: %.loc10_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc10_6.2: init () = call @Foo(%.loc10_7, %.loc10_10)
// CHECK:STDOUT: %.loc10_6.2: init () = call %Foo.ref.loc10(%.loc10_7, %.loc10_10)
// CHECK:STDOUT: %Foo.ref.loc11: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc11_7: i32 = int_literal 1
// CHECK:STDOUT: %.loc11_10: i32 = int_literal 2
// CHECK:STDOUT: %.loc11_6: init () = call @Foo(%.loc11_7, %.loc11_10)
// CHECK:STDOUT: %.loc11_6: init () = call %Foo.ref.loc11(%.loc11_7, %.loc11_10)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -24,6 +24,6 @@ fn Main() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Foo.ref: <function> = name_reference "Foo", package.%Foo
// CHECK:STDOUT: %.loc10_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc10_6.2: init () = call @Foo()
// CHECK:STDOUT: %.loc10_6.2: init () = call %Foo.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -27,7 +27,7 @@ fn Main() {
// CHECK:STDOUT: %.loc11_11.2: () = tuple_literal ()
// CHECK:STDOUT: %b: ref () = var "b"
// CHECK:STDOUT: %MakeImplicitEmptyTuple.ref: <function> = name_reference "MakeImplicitEmptyTuple", package.%MakeImplicitEmptyTuple
// CHECK:STDOUT: %.loc11_37: init () = call @MakeImplicitEmptyTuple()
// CHECK:STDOUT: %.loc11_37: init () = call %MakeImplicitEmptyTuple.ref()
// CHECK:STDOUT: assign %b, %.loc11_37
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -19,6 +19,6 @@ fn G() { F(); }
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc9_11.1: type = tuple_type ()
// CHECK:STDOUT: %.loc9_11.2: init () = call @F()
// CHECK:STDOUT: %.loc9_11.2: init () = call %F.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+3 -3
View File
@@ -47,16 +47,16 @@ fn If(b: bool) {
// CHECK:STDOUT: !if.then:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc13_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc13_6.2: init () = call @F()
// CHECK:STDOUT: %.loc13_6.2: init () = call %F.ref()
// CHECK:STDOUT: br !if.done
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc15: init () = call @G()
// CHECK:STDOUT: %.loc15: init () = call %G.ref()
// CHECK:STDOUT: br !if.done
// CHECK:STDOUT:
// CHECK:STDOUT: !if.done:
// CHECK:STDOUT: %H.ref: <function> = name_reference "H", package.%H
// CHECK:STDOUT: %.loc17: init () = call @H()
// CHECK:STDOUT: %.loc17: init () = call %H.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+2 -2
View File
@@ -38,11 +38,11 @@ fn If(b: bool) {
// CHECK:STDOUT: !if.then:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc12_6.1: type = tuple_type ()
// CHECK:STDOUT: %.loc12_6.2: init () = call @F()
// CHECK:STDOUT: %.loc12_6.2: init () = call %F.ref()
// CHECK:STDOUT: br !if.else
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc14: init () = call @G()
// CHECK:STDOUT: %.loc14: init () = call %G.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -41,7 +41,7 @@ fn G() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then:
// CHECK:STDOUT: %A.ref: <function> = name_reference "A", package.%A
// CHECK:STDOUT: %.loc11_24.1: init i32 = call @A()
// CHECK:STDOUT: %.loc11_24.1: init i32 = call %A.ref()
// CHECK:STDOUT: %.loc11_24.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc11_24.3: ref i32 = temporary %.loc11_24.2, %.loc11_24.1
// CHECK:STDOUT: %.loc11_24.4: i32 = bind_value %.loc11_24.3
@@ -49,7 +49,7 @@ fn G() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.else:
// CHECK:STDOUT: %B.ref: <function> = name_reference "B", package.%B
// CHECK:STDOUT: %.loc11_33.1: init i32 = call @B()
// CHECK:STDOUT: %.loc11_33.1: init i32 = call %B.ref()
// CHECK:STDOUT: %.loc11_33.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc11_33.3: ref i32 = temporary %.loc11_33.2, %.loc11_33.1
// CHECK:STDOUT: %.loc11_33.4: i32 = bind_value %.loc11_33.3
@@ -67,7 +67,7 @@ fn G() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then:
// CHECK:STDOUT: %A.ref: <function> = name_reference "A", package.%A
// CHECK:STDOUT: %.loc15_25.1: init i32 = call @A()
// CHECK:STDOUT: %.loc15_25.1: init i32 = call %A.ref()
// CHECK:STDOUT: %.loc15_25.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc15_25.3: ref i32 = temporary %.loc15_25.2, %.loc15_25.1
// CHECK:STDOUT: %.loc15_25.4: i32 = bind_value %.loc15_25.3
@@ -75,7 +75,7 @@ fn G() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.else:
// CHECK:STDOUT: %B.ref: <function> = name_reference "B", package.%B
// CHECK:STDOUT: %.loc15_34.1: init i32 = call @B()
// CHECK:STDOUT: %.loc15_34.1: init i32 = call %B.ref()
// CHECK:STDOUT: %.loc15_34.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc15_34.3: ref i32 = temporary %.loc15_34.2, %.loc15_34.1
// CHECK:STDOUT: %.loc15_34.4: i32 = bind_value %.loc15_34.3
+2 -2
View File
@@ -36,7 +36,7 @@ fn F(b: bool) -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.then:
// CHECK:STDOUT: %A.ref: <function> = name_reference "A", package.%A
// CHECK:STDOUT: %.loc11_21.1: init i32 = call @A()
// CHECK:STDOUT: %.loc11_21.1: init i32 = call %A.ref()
// CHECK:STDOUT: %.loc11_21.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc11_21.3: ref i32 = temporary %.loc11_21.2, %.loc11_21.1
// CHECK:STDOUT: %.loc11_21.4: i32 = bind_value %.loc11_21.3
@@ -44,7 +44,7 @@ fn F(b: bool) -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.expr.else:
// CHECK:STDOUT: %B.ref: <function> = name_reference "B", package.%B
// CHECK:STDOUT: %.loc11_30.1: init i32 = call @B()
// CHECK:STDOUT: %.loc11_30.1: init i32 = call %B.ref()
// CHECK:STDOUT: %.loc11_30.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc11_30.3: ref i32 = temporary %.loc11_30.2, %.loc11_30.1
// CHECK:STDOUT: %.loc11_30.4: i32 = bind_value %.loc11_30.3
+1 -1
View File
@@ -56,6 +56,6 @@ fn F(cond: bool) {
// CHECK:STDOUT: !if.expr.result:
// CHECK:STDOUT: %.loc11_5: {.a: i32, .b: i32} = block_arg !if.expr.result
// CHECK:STDOUT: %.loc11_4.1: type = tuple_type ()
// CHECK:STDOUT: %.loc11_4.2: init () = call @G(%.loc11_5)
// CHECK:STDOUT: %.loc11_4.2: init () = call %G.ref(%.loc11_5)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+1 -1
View File
@@ -98,7 +98,7 @@ fn ValueBinding(b: [i32; 3]) {
// CHECK:STDOUT: %.loc23_6.3: i32 = bind_value %.loc23_6.2
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc24_4.1: ref [i32; 3] = temporary_storage
// CHECK:STDOUT: %.loc24_4.2: init [i32; 3] = call @F() to %.loc24_4.1
// CHECK:STDOUT: %.loc24_4.2: init [i32; 3] = call %F.ref() to %.loc24_4.1
// CHECK:STDOUT: %.loc24_7: i32 = int_literal 0
// CHECK:STDOUT: %.loc24_4.3: ref [i32; 3] = temporary %.loc24_4.1, %.loc24_4.2
// CHECK:STDOUT: %.loc24_8.1: ref i32 = array_index %.loc24_4.3, %.loc24_7
@@ -27,7 +27,7 @@ fn Run() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc13_4.1: type = tuple_type ()
// CHECK:STDOUT: %.loc13_4.2: init () = call @F()
// CHECK:STDOUT: %.loc13_4.2: init () = call %F.ref()
// CHECK:STDOUT: %.loc13_7: i32 = int_literal 0
// CHECK:STDOUT: %.loc13_4.3: ref () = temporary_storage
// CHECK:STDOUT: %.loc13_4.4: ref () = temporary %.loc13_4.3, %.loc13_4.2
@@ -58,7 +58,7 @@ fn G(b: [i32; 3]) {
// CHECK:STDOUT: %pf: ref i32* = var "pf"
// CHECK:STDOUT: %F.ref.loc25: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc25_20.1: ref [i32; 3] = temporary_storage
// CHECK:STDOUT: %.loc25_20.2: init [i32; 3] = call @F() to %.loc25_20.1
// CHECK:STDOUT: %.loc25_20.2: init [i32; 3] = call %F.ref.loc25() to %.loc25_20.1
// CHECK:STDOUT: %.loc25_23: i32 = int_literal 0
// CHECK:STDOUT: %.loc25_20.3: ref [i32; 3] = temporary %.loc25_20.1, %.loc25_20.2
// CHECK:STDOUT: %.loc25_24.1: ref i32 = array_index %.loc25_20.3, %.loc25_23
@@ -67,7 +67,7 @@ fn G(b: [i32; 3]) {
// CHECK:STDOUT: assign %pf, %.loc25_18
// CHECK:STDOUT: %F.ref.loc29: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc29_4.1: ref [i32; 3] = temporary_storage
// CHECK:STDOUT: %.loc29_4.2: init [i32; 3] = call @F() to %.loc29_4.1
// CHECK:STDOUT: %.loc29_4.2: init [i32; 3] = call %F.ref.loc29() to %.loc29_4.1
// CHECK:STDOUT: %.loc29_7: i32 = int_literal 0
// CHECK:STDOUT: %.loc29_4.3: ref [i32; 3] = temporary %.loc29_4.1, %.loc29_4.2
// CHECK:STDOUT: %.loc29_8.1: ref i32 = array_index %.loc29_4.3, %.loc29_7
@@ -26,7 +26,7 @@ fn Run() -> i32 {
// CHECK:STDOUT: fn @Run() -> i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_11.1: init (i32,) = call @F()
// CHECK:STDOUT: %.loc10_11.1: init (i32,) = call %F.ref()
// CHECK:STDOUT: %.loc10_14: i32 = int_literal 0
// CHECK:STDOUT: %.loc10_11.2: ref (i32,) = temporary_storage
// CHECK:STDOUT: %.loc10_11.3: ref (i32,) = temporary %.loc10_11.2, %.loc10_11.1
+2 -1
View File
@@ -37,7 +37,8 @@ fn Bar() {
// CHECK:STDOUT: fn @Bar() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Foo.ref: <namespace> = name_reference "Foo", package.%.loc7
// CHECK:STDOUT: %Baz.ref: <function> = name_reference "Baz", package.%Baz.loc13
// CHECK:STDOUT: %.loc17_10.1: type = tuple_type ()
// CHECK:STDOUT: %.loc17_10.2: init () = call @Baz.2()
// CHECK:STDOUT: %.loc17_10.2: init () = call %Baz.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+3 -1
View File
@@ -30,7 +30,9 @@ fn Foo.Bar.Baz() {
// CHECK:STDOUT: fn @Baz() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Foo.ref: <namespace> = name_reference "Foo", package.%.loc7
// CHECK:STDOUT: %Bar.ref: <namespace> = name_reference "Bar", package.%.loc8
// CHECK:STDOUT: %Wiz.ref: <function> = name_reference "Wiz", package.%Wiz
// CHECK:STDOUT: %.loc14_14.1: type = tuple_type ()
// CHECK:STDOUT: %.loc14_14.2: init () = call @Wiz()
// CHECK:STDOUT: %.loc14_14.2: init () = call %Wiz.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+2 -2
View File
@@ -32,7 +32,7 @@ fn And() -> bool {
// CHECK:STDOUT: fn @And() -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc11_11.1: init bool = call @F()
// CHECK:STDOUT: %.loc11_11.1: init bool = call %F.ref()
// CHECK:STDOUT: %.loc11_11.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc11_11.3: ref bool = temporary %.loc11_11.2, %.loc11_11.1
// CHECK:STDOUT: %.loc11_11.4: bool = bind_value %.loc11_11.3
@@ -41,7 +41,7 @@ fn And() -> bool {
// CHECK:STDOUT:
// CHECK:STDOUT: !and.rhs:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc11_19.1: init bool = call @G()
// CHECK:STDOUT: %.loc11_19.1: init bool = call %G.ref()
// CHECK:STDOUT: %.loc11_19.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc11_19.3: ref bool = temporary %.loc11_19.2, %.loc11_19.1
// CHECK:STDOUT: %.loc11_19.4: bool = bind_value %.loc11_19.3
@@ -58,7 +58,7 @@ fn Main() {
// CHECK:STDOUT: %.loc13_7: i32 = int_literal 2
// CHECK:STDOUT: assign %.loc13_3, %.loc13_7
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc17_4: init i32 = call @F()
// CHECK:STDOUT: %.loc17_4: init i32 = call %F.ref()
// CHECK:STDOUT: %.loc17_9: i32 = int_literal 1
// CHECK:STDOUT: assign %.loc17_4, %.loc17_9
// CHECK:STDOUT: %.loc21_4: i32 = int_literal 1
+2 -2
View File
@@ -32,7 +32,7 @@ fn Or() -> bool {
// CHECK:STDOUT: fn @Or() -> bool {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc11_11.1: init bool = call @F()
// CHECK:STDOUT: %.loc11_11.1: init bool = call %F.ref()
// CHECK:STDOUT: %.loc11_11.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc11_11.3: ref bool = temporary %.loc11_11.2, %.loc11_11.1
// CHECK:STDOUT: %.loc11_11.4: bool = bind_value %.loc11_11.3
@@ -42,7 +42,7 @@ fn Or() -> bool {
// CHECK:STDOUT:
// CHECK:STDOUT: !or.rhs:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc11_18.1: init bool = call @G()
// CHECK:STDOUT: %.loc11_18.1: init bool = call %G.ref()
// CHECK:STDOUT: %.loc11_18.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc11_18.3: ref bool = temporary %.loc11_18.2, %.loc11_18.1
// CHECK:STDOUT: %.loc11_18.4: bool = bind_value %.loc11_18.3
@@ -131,7 +131,7 @@ fn AddressOfParameter(param: i32) {
// CHECK:STDOUT: %.loc42_7: i32 = add %.loc42_5, %.loc42_9
// CHECK:STDOUT: %.loc42_3: i32* = address_of %.loc42_7
// CHECK:STDOUT: %H.ref: <function> = name_reference "H", package.%H
// CHECK:STDOUT: %.loc46_5.1: init {.a: i32} = call @H()
// CHECK:STDOUT: %.loc46_5.1: init {.a: i32} = call %H.ref()
// CHECK:STDOUT: %.loc46_5.2: ref {.a: i32} = temporary_storage
// CHECK:STDOUT: %.loc46_5.3: ref {.a: i32} = temporary %.loc46_5.2, %.loc46_5.1
// CHECK:STDOUT: %.loc46_7: ref i32 = struct_access %.loc46_5.3, member0
@@ -145,7 +145,7 @@ fn AddressOfParameter(param: i32) {
// CHECK:STDOUT: fn @AddressOfCall() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc57_5: init i32 = call @G()
// CHECK:STDOUT: %.loc57_5: init i32 = call %G.ref()
// CHECK:STDOUT: %.loc57_3: i32* = address_of %.loc57_5
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -22,7 +22,7 @@ fn F() -> i32 {
// CHECK:STDOUT: %.loc10_16: i32 = int_literal 1
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc10_25.1: ref {.x: i32, .y: i32, .z: i32} = temporary_storage
// CHECK:STDOUT: %.loc10_25.2: init {.x: i32, .y: i32, .z: i32} = call @G() to %.loc10_25.1
// CHECK:STDOUT: %.loc10_25.2: init {.x: i32, .y: i32, .z: i32} = call %G.ref() to %.loc10_25.1
// CHECK:STDOUT: %.loc10_34: i32 = int_literal 3
// CHECK:STDOUT: %.loc10_35.1: type = struct_type {.a: i32, .b: {.x: i32, .y: i32, .z: i32}, .c: i32}
// CHECK:STDOUT: %.loc10_35.2: {.a: i32, .b: {.x: i32, .y: i32, .z: i32}, .c: i32} = struct_literal (%.loc10_16, %.loc10_25.2, %.loc10_34)
@@ -25,10 +25,10 @@ fn G() {
// CHECK:STDOUT: %v: ref {.a: (i32, i32, i32), .b: (i32, i32, i32)} = var "v"
// CHECK:STDOUT: %F.ref.loc10_61: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_74.1: ref (i32, i32, i32) = struct_access %v, member0
// CHECK:STDOUT: %.loc10_62: init (i32, i32, i32) = call @F() to %.loc10_74.1
// CHECK:STDOUT: %.loc10_62: init (i32, i32, i32) = call %F.ref.loc10_61() to %.loc10_74.1
// CHECK:STDOUT: %F.ref.loc10_71: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_74.2: ref (i32, i32, i32) = struct_access %v, member1
// CHECK:STDOUT: %.loc10_72: init (i32, i32, i32) = call @F() to %.loc10_74.2
// CHECK:STDOUT: %.loc10_72: init (i32, i32, i32) = call %F.ref.loc10_71() to %.loc10_74.2
// CHECK:STDOUT: %.loc10_74.3: {.a: (i32, i32, i32), .b: (i32, i32, i32)} = struct_literal (%.loc10_62, %.loc10_72)
// CHECK:STDOUT: %.loc10_74.4: init {.a: (i32, i32, i32), .b: (i32, i32, i32)} = struct_init %.loc10_74.3, (%.loc10_62, %.loc10_72)
// CHECK:STDOUT: assign %v, %.loc10_74.4
@@ -32,10 +32,10 @@ fn H() {
// CHECK:STDOUT: %v: ref ((i32, i32, i32), (i32, i32, i32)) = var "v"
// CHECK:STDOUT: %F.ref.loc10_48: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_56.1: ref (i32, i32, i32) = tuple_access %v, member0
// CHECK:STDOUT: %.loc10_49: init (i32, i32, i32) = call @F() to %.loc10_56.1
// CHECK:STDOUT: %.loc10_49: init (i32, i32, i32) = call %F.ref.loc10_48() to %.loc10_56.1
// CHECK:STDOUT: %F.ref.loc10_53: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc10_56.2: ref (i32, i32, i32) = tuple_access %v, member1
// CHECK:STDOUT: %.loc10_54: init (i32, i32, i32) = call @F() to %.loc10_56.2
// CHECK:STDOUT: %.loc10_54: init (i32, i32, i32) = call %F.ref.loc10_53() to %.loc10_56.2
// CHECK:STDOUT: %.loc10_56.3: ((i32, i32, i32), (i32, i32, i32)) = tuple_literal (%.loc10_49, %.loc10_54)
// CHECK:STDOUT: %.loc10_56.4: init ((i32, i32, i32), (i32, i32, i32)) = tuple_init %.loc10_56.3, (%.loc10_49, %.loc10_54)
// CHECK:STDOUT: assign %v, %.loc10_56.4
@@ -52,7 +52,7 @@ fn H() {
// CHECK:STDOUT: %.loc14_41: i32 = int_literal 1
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc14_50.1: ref (i32, i32, i32) = tuple_access %v, member1
// CHECK:STDOUT: %.loc14_45: init (i32, i32, i32) = call @F() to %.loc14_50.1
// CHECK:STDOUT: %.loc14_45: init (i32, i32, i32) = call %F.ref() to %.loc14_50.1
// CHECK:STDOUT: %.loc14_49: i32 = int_literal 2
// CHECK:STDOUT: %.loc14_50.2: (i32, (i32, i32, i32), i32) = tuple_literal (%.loc14_41, %.loc14_45, %.loc14_49)
// CHECK:STDOUT: %.loc14_50.3: ref i32 = tuple_access %v, member0
+8 -8
View File
@@ -60,7 +60,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.cond.loc17:
// CHECK:STDOUT: %A.ref: <function> = name_reference "A", package.%A
// CHECK:STDOUT: %.loc17_11.1: init bool = call @A()
// CHECK:STDOUT: %.loc17_11.1: init bool = call %A.ref()
// CHECK:STDOUT: %.loc17_11.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc17_11.3: ref bool = temporary %.loc17_11.2, %.loc17_11.1
// CHECK:STDOUT: %.loc17_11.4: bool = bind_value %.loc17_11.3
@@ -68,7 +68,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.body.loc17:
// CHECK:STDOUT: %B.ref: <function> = name_reference "B", package.%B
// CHECK:STDOUT: %.loc18_10.1: init bool = call @B()
// CHECK:STDOUT: %.loc18_10.1: init bool = call %B.ref()
// CHECK:STDOUT: %.loc18_10.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc18_10.3: ref bool = temporary %.loc18_10.2, %.loc18_10.1
// CHECK:STDOUT: %.loc18_10.4: bool = bind_value %.loc18_10.3
@@ -79,7 +79,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc18:
// CHECK:STDOUT: %C.ref: <function> = name_reference "C", package.%C
// CHECK:STDOUT: %.loc19_10.1: init bool = call @C()
// CHECK:STDOUT: %.loc19_10.1: init bool = call %C.ref()
// CHECK:STDOUT: %.loc19_10.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc19_10.3: ref bool = temporary %.loc19_10.2, %.loc19_10.1
// CHECK:STDOUT: %.loc19_10.4: bool = bind_value %.loc19_10.3
@@ -93,7 +93,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.cond.loc20:
// CHECK:STDOUT: %D.ref: <function> = name_reference "D", package.%D
// CHECK:STDOUT: %.loc20_13.1: init bool = call @D()
// CHECK:STDOUT: %.loc20_13.1: init bool = call %D.ref()
// CHECK:STDOUT: %.loc20_13.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc20_13.3: ref bool = temporary %.loc20_13.2, %.loc20_13.1
// CHECK:STDOUT: %.loc20_13.4: bool = bind_value %.loc20_13.3
@@ -101,7 +101,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.body.loc20:
// CHECK:STDOUT: %E.ref: <function> = name_reference "E", package.%E
// CHECK:STDOUT: %.loc21_12.1: init bool = call @E()
// CHECK:STDOUT: %.loc21_12.1: init bool = call %E.ref()
// CHECK:STDOUT: %.loc21_12.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc21_12.3: ref bool = temporary %.loc21_12.2, %.loc21_12.1
// CHECK:STDOUT: %.loc21_12.4: bool = bind_value %.loc21_12.3
@@ -112,7 +112,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc21:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc22_12.1: init bool = call @F()
// CHECK:STDOUT: %.loc22_12.1: init bool = call %F.ref()
// CHECK:STDOUT: %.loc22_12.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc22_12.3: ref bool = temporary %.loc22_12.2, %.loc22_12.1
// CHECK:STDOUT: %.loc22_12.4: bool = bind_value %.loc22_12.3
@@ -126,7 +126,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.done.loc20:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc24_10.1: init bool = call @G()
// CHECK:STDOUT: %.loc24_10.1: init bool = call %G.ref()
// CHECK:STDOUT: %.loc24_10.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc24_10.3: ref bool = temporary %.loc24_10.2, %.loc24_10.1
// CHECK:STDOUT: %.loc24_10.4: bool = bind_value %.loc24_10.3
@@ -137,7 +137,7 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else.loc24:
// CHECK:STDOUT: %H.ref: <function> = name_reference "H", package.%H
// CHECK:STDOUT: %.loc25_10.1: init bool = call @H()
// CHECK:STDOUT: %.loc25_10.1: init bool = call %H.ref()
// CHECK:STDOUT: %.loc25_10.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc25_10.3: ref bool = temporary %.loc25_10.2, %.loc25_10.1
// CHECK:STDOUT: %.loc25_10.4: bool = bind_value %.loc25_10.3
+4 -4
View File
@@ -39,12 +39,12 @@ fn While() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc14_4.1: type = tuple_type ()
// CHECK:STDOUT: %.loc14_4.2: init () = call @F()
// CHECK:STDOUT: %.loc14_4.2: init () = call %F.ref()
// CHECK:STDOUT: br !while.cond
// CHECK:STDOUT:
// CHECK:STDOUT: !while.cond:
// CHECK:STDOUT: %Cond.ref: <function> = name_reference "Cond", package.%Cond
// CHECK:STDOUT: %.loc15_14.1: init bool = call @Cond()
// CHECK:STDOUT: %.loc15_14.1: init bool = call %Cond.ref()
// CHECK:STDOUT: %.loc15_14.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc15_14.3: ref bool = temporary %.loc15_14.2, %.loc15_14.1
// CHECK:STDOUT: %.loc15_14.4: bool = bind_value %.loc15_14.3
@@ -52,11 +52,11 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.body:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc16: init () = call @G()
// CHECK:STDOUT: %.loc16: init () = call %G.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT:
// CHECK:STDOUT: !while.done:
// CHECK:STDOUT: %H.ref: <function> = name_reference "H", package.%H
// CHECK:STDOUT: %.loc19: init () = call @H()
// CHECK:STDOUT: %.loc19: init () = call %H.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+4 -4
View File
@@ -38,12 +38,12 @@ fn While() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: <function> = name_reference "F", package.%F
// CHECK:STDOUT: %.loc14_4.1: type = tuple_type ()
// CHECK:STDOUT: %.loc14_4.2: init () = call @F()
// CHECK:STDOUT: %.loc14_4.2: init () = call %F.ref()
// CHECK:STDOUT: br !while.cond
// CHECK:STDOUT:
// CHECK:STDOUT: !while.cond:
// CHECK:STDOUT: %Cond.ref: <function> = name_reference "Cond", package.%Cond
// CHECK:STDOUT: %.loc15_14.1: init bool = call @Cond()
// CHECK:STDOUT: %.loc15_14.1: init bool = call %Cond.ref()
// CHECK:STDOUT: %.loc15_14.2: ref bool = temporary_storage
// CHECK:STDOUT: %.loc15_14.3: ref bool = temporary %.loc15_14.2, %.loc15_14.1
// CHECK:STDOUT: %.loc15_14.4: bool = bind_value %.loc15_14.3
@@ -51,11 +51,11 @@ fn While() {
// CHECK:STDOUT:
// CHECK:STDOUT: !while.body:
// CHECK:STDOUT: %G.ref: <function> = name_reference "G", package.%G
// CHECK:STDOUT: %.loc16: init () = call @G()
// CHECK:STDOUT: %.loc16: init () = call %G.ref()
// CHECK:STDOUT: br !while.cond
// CHECK:STDOUT:
// CHECK:STDOUT: !while.done:
// CHECK:STDOUT: %H.ref: <function> = name_reference "H", package.%H
// CHECK:STDOUT: %.loc18: init () = call @H()
// CHECK:STDOUT: %.loc18: init () = call %H.ref()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+19 -18
View File
@@ -129,14 +129,14 @@ auto HandleBuiltin(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/,
auto HandleCall(FunctionContext& context, SemIR::NodeId node_id,
SemIR::Call node) -> void {
auto* llvm_function = context.GetFunction(node.function_id);
const auto& function = context.semantics_ir().GetFunction(node.function_id);
auto* callee = llvm::cast<llvm::Function>(context.GetLocal(node.callee_id));
std::vector<llvm::Value*> args;
llvm::ArrayRef<SemIR::NodeId> arg_ids =
context.semantics_ir().GetNodeBlock(node.args_id);
if (function.return_slot_id.is_valid()) {
if (SemIR::GetInitializingRepresentation(context.semantics_ir(), node.type_id)
.has_return_slot()) {
args.push_back(context.GetLocal(arg_ids.back()));
arg_ids = arg_ids.drop_back();
}
@@ -149,17 +149,13 @@ auto HandleCall(FunctionContext& context, SemIR::NodeId node_id,
}
}
if (llvm_function->getReturnType()->isVoidTy()) {
context.builder().CreateCall(llvm_function, args);
// The value of a function call with a void return type shouldn't used, but
// StubReference needs a value to propagate.
// TODO: Remove this now the StubReferences are gone.
context.SetLocal(node_id,
llvm::PoisonValue::get(context.GetType(node.type_id)));
} else {
context.SetLocal(node_id,
context.builder().CreateCall(llvm_function, args,
llvm_function->getName()));
auto* call = context.builder().CreateCall(callee, args);
context.SetLocal(node_id, call);
// Name the call's result the same as the callee.
// TODO: Is this a helpful name?
if (!call->getType()->isVoidTy()) {
call->setName(callee->getName());
}
}
@@ -202,12 +198,17 @@ auto HandleNameReference(FunctionContext& context, SemIR::NodeId node_id,
SemIR::NameReference node) -> void {
auto type_node_id =
context.semantics_ir().GetTypeAllowBuiltinTypes(node.type_id);
if (type_node_id == SemIR::NodeId::BuiltinFunctionType ||
type_node_id == SemIR::NodeId::BuiltinNamespaceType) {
if (type_node_id == SemIR::NodeId::BuiltinNamespaceType) {
return;
}
// TODO: Handle name references to globals
context.SetLocal(node_id, context.GetLocal(node.value_id));
auto target = context.semantics_ir().GetNode(node.value_id);
if (auto function_decl = target.TryAs<SemIR::FunctionDeclaration>()) {
context.SetLocal(node_id, context.GetFunction(function_decl->function_id));
} else {
// TODO: Handle other kinds of name references to globals.
context.SetLocal(node_id, context.GetLocal(node.value_id));
}
}
auto HandleNamespace(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/,
+3 -2
View File
@@ -698,12 +698,13 @@ class Formatter {
auto FormatInstructionRHS(Call node) -> void {
out_ << " ";
FormatArg(node.function_id);
FormatArg(node.callee_id);
llvm::ArrayRef<NodeId> args = semantics_ir_.GetNodeBlock(node.args_id);
bool has_return_slot =
semantics_ir_.GetFunction(node.function_id).return_slot_id.is_valid();
GetInitializingRepresentation(semantics_ir_, node.type_id)
.has_return_slot();
NodeId return_slot_id = NodeId::Invalid;
if (has_return_slot) {
return_slot_id = args.back();
+1 -1
View File
@@ -313,8 +313,8 @@ struct Builtin {
};
struct Call {
NodeId callee_id;
NodeBlockId args_id;
FunctionId function_id;
};
struct ClassDeclaration {