Semantic analysis for if expressions (#2893)

Add semantic analysis and semantics IR building for `if` expressions, and add the first parts of control flow handling to semantics IR. After discussion with @chandlerc, use [block arguments](https://en.wikipedia.org/wiki/Static_single-assignment_form#Block_arguments) to convey values from the two arms of the `if` to the result. For now, only a single block argument is supported, but we should revisit this as we explore more of the requirements of the Semantics IR form.

Functions can now contain multiple code blocks, so grab the entry block up-front instead of assuming the entry block will be at the top of the block stack when we reach the end of function emission.

Add trivial support for `bool` type literal, because without it we can't write testcases.
This commit is contained in:
Richard Smith
2023-06-13 14:38:27 -07:00
committed by GitHub
parent 9606ce2127
commit 202d3f5993
43 changed files with 646 additions and 161 deletions
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block2},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -26,6 +26,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+0,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Main() {
@@ -5,10 +5,10 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block3, body: block0},
// CHECK:STDOUT: {name: str4, param_refs: block5, body: block0},
// CHECK:STDOUT: {name: str5, param_refs: block0, body: block6},
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block2},
// CHECK:STDOUT: {name: str2, param_refs: block4, body: block5},
// CHECK:STDOUT: {name: str4, param_refs: block7, body: block8},
// CHECK:STDOUT: {name: str5, param_refs: block0, body: block9},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -66,6 +66,8 @@
// CHECK:STDOUT: node+9,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
@@ -73,6 +75,8 @@
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: node+6,
@@ -83,6 +87,8 @@
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+10,
// CHECK:STDOUT: node+11,
// CHECK:STDOUT: node+12,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -46,6 +46,8 @@
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str3, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str4, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str3, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str4, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -50,7 +50,7 @@
// CHECK:STDOUT: {kind: StubReference, arg0: node+16, type: type0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int5, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+18, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block5, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
@@ -73,6 +73,8 @@
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+8,
// CHECK:STDOUT: node+9,
// CHECK:STDOUT: node+10,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -29,7 +29,7 @@
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block5, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
@@ -46,6 +46,8 @@
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: node+6,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -30,10 +30,10 @@
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block5, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block7, arg1: function0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
@@ -50,6 +50,8 @@
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: node+6,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str3, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str3, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -35,7 +35,7 @@
// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block5, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
@@ -55,6 +55,8 @@
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+6,
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: node+8,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str3, param_refs: block0, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str3, param_refs: block0, body: block5},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
@@ -37,12 +37,12 @@
// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block5, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+11, type: type0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type0},
// CHECK:STDOUT: {kind: StubReference, arg0: node+13, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0},
// CHECK:STDOUT: {kind: Call, arg0: block7, arg1: function0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
@@ -62,6 +62,8 @@
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+6,
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: node+8,
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block0, body: block2},
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block2},
// CHECK:STDOUT: {name: str1, param_refs: block0, body: block3},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -32,6 +32,8 @@
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -42,6 +42,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
// CHECK:STDERR: fail_param_name_conflict.carbon:[[@LINE+2]]:16: Redefining a in the same scope.
@@ -5,9 +5,9 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block2},
// CHECK:STDOUT: {name: str1, param_refs: block0, body: block3},
// CHECK:STDOUT: {name: str2, param_refs: block0, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -34,6 +34,12 @@
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo() {}
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -37,6 +37,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo(a: i32) {}
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -37,6 +37,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo(a: i32,) {}
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -43,6 +43,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo(a: i32, b: i32) {}
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block2, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -43,6 +43,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo(a: i32, b: i32,) {}
@@ -5,7 +5,7 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block0},
// CHECK:STDOUT: {name: str0, param_refs: block0, body: block2},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -26,6 +26,8 @@
// CHECK:STDOUT: [
// CHECK:STDOUT: node+0,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo() {}
@@ -5,8 +5,8 @@
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block0},
// CHECK:STDOUT: {name: str2, param_refs: block5, body: block0},
// CHECK:STDOUT: {name: str1, param_refs: block2, body: block4},
// CHECK:STDOUT: {name: str2, param_refs: block6, body: block7},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
@@ -44,12 +44,16 @@
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn Foo(a: i32) {}
+80
View File
@@ -0,0 +1,80 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str3, param_refs: block2, return_type: type1, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: ]
// CHECK:STDOUT: real_literals: [
// CHECK:STDOUT: ]
// CHECK:STDOUT: strings: [
// CHECK:STDOUT: b,
// CHECK:STDOUT: n,
// CHECK:STDOUT: m,
// CHECK:STDOUT: F,
// CHECK:STDOUT: ]
// CHECK:STDOUT: types: [
// CHECK:STDOUT: nodeBoolType,
// CHECK:STDOUT: nodeIntegerType,
// CHECK:STDOUT: ]
// CHECK:STDOUT: nodes: [
// CHECK:STDOUT: {kind: VarStorage, type: type0},
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node+0, type: type0},
// CHECK:STDOUT: {kind: VarStorage, type: type1},
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+2, type: type1},
// CHECK:STDOUT: {kind: VarStorage, type: type1},
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+4, type: type1},
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
// CHECK:STDOUT: {kind: BranchIf, arg0: block6, arg1: node+0},
// CHECK:STDOUT: {kind: Branch, arg0: block5},
// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+2, arg1: node+4, type: type1},
// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+4, arg1: node+2, type: type1},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+9},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+10},
// CHECK:STDOUT: {kind: BlockArg, type: type1},
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+13, type: type1},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+0,
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+6,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: node+8,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+10,
// CHECK:STDOUT: node+12,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+9,
// CHECK:STDOUT: node+11,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+13,
// CHECK:STDOUT: node+14,
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn F(b: bool, n: i32, m: i32) -> i32 {
return if b then n + m else m + n;
}
@@ -0,0 +1,93 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: block2},
// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type0, body: block3},
// CHECK:STDOUT: {name: str3, param_refs: block5, return_type: type0, body: block6},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
// CHECK:STDOUT: 2,
// CHECK:STDOUT: ]
// CHECK:STDOUT: real_literals: [
// CHECK:STDOUT: ]
// CHECK:STDOUT: strings: [
// CHECK:STDOUT: A,
// CHECK:STDOUT: B,
// CHECK:STDOUT: b,
// CHECK:STDOUT: F,
// CHECK:STDOUT: ]
// CHECK:STDOUT: types: [
// CHECK:STDOUT: nodeIntegerType,
// CHECK:STDOUT: nodeBoolType,
// CHECK:STDOUT: ]
// CHECK:STDOUT: nodes: [
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0},
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1, type: type0},
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0},
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4, type: type0},
// CHECK:STDOUT: {kind: VarStorage, type: type1},
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+6, type: type1},
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2},
// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+6},
// CHECK:STDOUT: {kind: Branch, arg0: block7},
// CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0},
// CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+11},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+12},
// CHECK:STDOUT: {kind: BlockArg, type: type0},
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+15, type: type0},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+0,
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+8,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+6,
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+9,
// CHECK:STDOUT: node+10,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+12,
// CHECK:STDOUT: node+14,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+11,
// CHECK:STDOUT: node+13,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+15,
// CHECK:STDOUT: node+16,
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn A() -> i32 { return 1; }
fn B() -> i32 { return 2; }
fn F(b: bool) -> i32 {
return if b then A() else B();
}
+120
View File
@@ -0,0 +1,120 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// CHECK:STDOUT: cross_reference_irs_size: 1
// CHECK:STDOUT: functions: [
// CHECK:STDOUT: {name: str3, param_refs: block2, return_type: type1, body: block4},
// CHECK:STDOUT: ]
// CHECK:STDOUT: integer_literals: [
// CHECK:STDOUT: 1,
// CHECK:STDOUT: 2,
// CHECK:STDOUT: 3,
// CHECK:STDOUT: 4,
// CHECK:STDOUT: ]
// CHECK:STDOUT: real_literals: [
// CHECK:STDOUT: ]
// CHECK:STDOUT: strings: [
// CHECK:STDOUT: a,
// CHECK:STDOUT: b,
// CHECK:STDOUT: c,
// CHECK:STDOUT: F,
// CHECK:STDOUT: ]
// CHECK:STDOUT: types: [
// CHECK:STDOUT: nodeBoolType,
// CHECK:STDOUT: nodeIntegerType,
// CHECK:STDOUT: ]
// CHECK:STDOUT: nodes: [
// CHECK:STDOUT: {kind: VarStorage, type: type0},
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node+0, type: type0},
// CHECK:STDOUT: {kind: VarStorage, type: type0},
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node+2, type: type0},
// CHECK:STDOUT: {kind: VarStorage, type: type0},
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node+4, type: type0},
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
// CHECK:STDOUT: {kind: BranchIf, arg0: block6, arg1: node+0},
// CHECK:STDOUT: {kind: Branch, arg0: block5},
// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+2},
// CHECK:STDOUT: {kind: Branch, arg0: block7},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+11},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+12},
// CHECK:STDOUT: {kind: BlockArg, type: type1},
// CHECK:STDOUT: {kind: BranchIf, arg0: block11, arg1: node+4},
// CHECK:STDOUT: {kind: Branch, arg0: block10},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type1},
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type1},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block12, arg1: node+18},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block12, arg1: node+19},
// CHECK:STDOUT: {kind: BlockArg, type: type1},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+15},
// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+22},
// CHECK:STDOUT: {kind: BlockArg, type: type1},
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+25, type: type1},
// CHECK:STDOUT: ]
// CHECK:STDOUT: node_blocks: [
// CHECK:STDOUT: [
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+0,
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+2,
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+4,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+1,
// CHECK:STDOUT: node+3,
// CHECK:STDOUT: node+5,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+6,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+7,
// CHECK:STDOUT: node+8,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+16,
// CHECK:STDOUT: node+17,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+9,
// CHECK:STDOUT: node+10,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+12,
// CHECK:STDOUT: node+14,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+11,
// CHECK:STDOUT: node+13,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+15,
// CHECK:STDOUT: node+23,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+19,
// CHECK:STDOUT: node+21,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+18,
// CHECK:STDOUT: node+20,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+22,
// CHECK:STDOUT: node+24,
// CHECK:STDOUT: ],
// CHECK:STDOUT: [
// CHECK:STDOUT: node+25,
// CHECK:STDOUT: node+26,
// CHECK:STDOUT: ],
// CHECK:STDOUT: ]
fn F(a: bool, b: bool, c: bool) -> i32 {
return if a then if b then 1 else 2 else if c then 3 else 4;
}