Implement SILGen for multi-pattern conditions in if/while, finishing the

known implementation work required for:
<rdar://problem/19382942> Improve 'if let' to avoid optional pyramid of doom

I want to write some more tests and improve error recovery QoI in the parser,
but I believe it fully works now.  Please kick the tires and let me know if
you observe any problems (other than 19432424 which was pre-existing).



Swift SVN r24348
This commit is contained in:
Chris Lattner
2015-01-10 01:59:47 +00:00
parent 7faecf021e
commit b2e11e4da5
3 changed files with 285 additions and 151 deletions

View File

@@ -94,8 +94,6 @@ func while_loop() {
}
// CHECK: [[LOOP_EXIT]]:
// CHECK: destroy_addr [[OPT_BUF]]
// CHECK: br [[LOOP_END]]
// CHECK: [[LOOP_END]]:
// CHECK: dealloc_stack [[OPT_BUF]]
}
@@ -114,3 +112,37 @@ func while_loop_generic<T>(source: () -> T?) {
while let x = source() {
}
}
// <rdar://problem/19382942> Improve 'if let' to avoid optional pyramid of doom
// CHECK-LABEL: sil hidden @_TF16if_while_binding16while_loop_multiFT_T_
func while_loop_multi() {
// CHECK: [[OPT_BUF1:%.*]] = alloc_stack $Optional<String>
// CHECK: [[OPT_BUF2:%.*]] = alloc_stack $Optional<String>
// CHECK: br [[LOOP_ENTRY:bb[0-9]+]]
// CHECK: [[LOOP_ENTRY]]:
// CHECK: [[HAS_VALUE1:%.*]] = select_enum_addr [[OPT_BUF1]]#1
// CHECK: cond_br [[HAS_VALUE1]], [[CHECKBUF2:bb[0-9]+]], [[LOOP_EXIT1:bb[0-9]+]]
// CHECK: [[CHECKBUF2]]:
// CHECK: [[HAS_VALUE2:%.*]] = select_enum_addr [[OPT_BUF2]]#1
// CHECK: cond_br [[HAS_VALUE2]], [[LOOP_BODY:bb[0-9]+]], [[LOOP_EXIT2:bb[0-9]+]]
// CHECK: [[LOOP_BODY]]:
while let a = foo(), b = bar() {
// CHECK: [[VAL_BUF1:%.*]] = unchecked_take_enum_data_addr [[OPT_BUF1]]#1
// CHECK: debug_value {{.*}} : $String // let a
// CHECK: [[VAL_BUF2:%.*]] = unchecked_take_enum_data_addr [[OPT_BUF2]]#1
// CHECK: debug_value {{.*}} : $String // let b
// CHECK: debug_value {{.*}} : $String // let c
// CHECK: br [[LOOP_ENTRY]]
let c = a
}
// CHECK: [[LOOP_EXIT2]]:
// CHECK: destroy_addr [[OPT_BUF2]]#1
// CHECK: br [[LOOP_EXIT1]]
// CHECK: [[LOOP_EXIT1]]:
// CHECK: destroy_addr [[OPT_BUF1]]#1
// CHECK: dealloc_stack [[OPT_BUF2]]#0
// CHECK: dealloc_stack [[OPT_BUF1]]#0
}