Files
swift-mirror/test/SILGen/functions.swift
Adrian Prantl c9927f66f0 Serialize debug scope and location info in the SIL assembler language.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.

The new syntax is as follows:

 sil-scope-ref ::= 'scope' [0-9]+
 sil-scope ::= 'sil_scope' [0-9]+ '{'
                 sil-loc
                 'parent' scope-parent
                 ('inlined_at' sil-scope-ref )?
               '}'
 scope-parent ::= sil-function-name ':' sil-type
 scope-parent ::= sil-scope-ref
 sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+

Each instruction may have a debug location and a SIL scope reference
at the end.  Debug locations consist of a filename, a line number, and
a column number.  If the debug location is omitted, it defaults to the
location in the SIL source file.  SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.

<rdar://problem/22706994>
2016-02-26 10:46:29 -08:00

482 lines
21 KiB
Swift

// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -parse-stdlib -parse-as-library -emit-silgen %s | FileCheck %s
import Swift // just for Optional
func markUsed<T>(t: T) {}
typealias Int = Builtin.Int64
typealias Int64 = Builtin.Int64
typealias Bool = Builtin.Int1
var zero = getInt()
func getInt() -> Int { return zero }
func standalone_function(x: Int, _ y: Int) -> Int {
return x
}
func higher_order_function(f: (x: Int, y: Int) -> Int, _ x: Int, _ y: Int) -> Int {
return f(x: x, y: y)
}
func higher_order_function2(f: (Int, Int) -> Int, _ x: Int, _ y: Int) -> Int {
return f(x, y)
}
struct SomeStruct {
// -- Constructors and methods are uncurried in 'self'
// -- Instance methods use 'method' cc
init(x:Int, y:Int) {}
mutating
func method(x: Int) {}
static func static_method(x: Int) {}
func generic_method<T>(x: T) {}
}
class SomeClass {
// -- Constructors and methods are uncurried in 'self'
// -- Instance methods use 'method' cc
// CHECK-LABEL: sil hidden @_TFC9functions9SomeClassc{{.*}} : $@convention(method) (Builtin.Int64, Builtin.Int64, @owned SomeClass) -> @owned SomeClass
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $SomeClass):
// CHECK-LABEL: sil hidden @_TFC9functions9SomeClassC{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, @thick SomeClass.Type) -> @owned SomeClass
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $@thick SomeClass.Type):
init(x:Int, y:Int) {}
// CHECK-LABEL: sil hidden @_TFC9functions9SomeClass6method{{.*}} : $@convention(method) (Builtin.Int64, @guaranteed SomeClass) -> ()
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $SomeClass):
func method(x: Int) {}
// CHECK-LABEL: sil hidden @_TZFC9functions9SomeClass13static_method{{.*}} : $@convention(thin) (Builtin.Int64, @thick SomeClass.Type) -> ()
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $@thick SomeClass.Type):
class func static_method(x: Int) {}
var someProperty: Int {
get {
return zero
}
set {}
}
subscript(x:Int, y:Int) -> Int {
get {
return zero
}
set {}
}
func generic<T>(x: T) -> T {
return x
}
}
func SomeClassWithBenefits() -> SomeClass.Type {
return SomeClass.self
}
protocol SomeProtocol {
func method(x: Int)
static func static_method(x: Int)
}
struct ConformsToSomeProtocol : SomeProtocol {
func method(x: Int) { }
static func static_method(x: Int) { }
}
class SomeGeneric<T> {
init() { }
func method(x: T) -> T { return x }
func generic<U>(x: U) -> U { return x }
}
// CHECK-LABEL: sil hidden @_TF9functions5calls{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, Builtin.Int64) -> ()
func calls(i:Int, j:Int, k:Int) {
var i = i
var j = j
var k = k
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $Builtin.Int64):
// CHECK: [[IBOX:%[0-9]+]] = alloc_box $Builtin.Int64
// CHECK: [[IADDR:%.*]] = project_box [[IBOX]]
// CHECK: [[JBOX:%[0-9]+]] = alloc_box $Builtin.Int64
// CHECK: [[JADDR:%.*]] = project_box [[JBOX]]
// CHECK: [[KBOX:%[0-9]+]] = alloc_box $Builtin.Int64
// CHECK: [[KADDR:%.*]] = project_box [[KBOX]]
// CHECK: [[FUNC:%[0-9]+]] = function_ref @_TF9functions19standalone_function{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: apply [[FUNC]]([[I]], [[J]])
standalone_function(i, j)
// -- Curry 'self' onto struct method argument lists.
// CHECK: [[ST_ADDR:%.*]] = alloc_box $SomeStruct
// CHECK: [[CTOR:%.*]] = function_ref @_TFV9functions10SomeStructC{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, @thin SomeStruct.Type) -> SomeStruct
// CHECK: [[METATYPE:%.*]] = metatype $@thin SomeStruct.Type
// CHECK: [[I:%.*]] = load [[IADDR]]
// CHECK: [[J:%.*]] = load [[JADDR]]
// CHECK: apply [[CTOR]]([[I]], [[J]], [[METATYPE]]) : $@convention(thin) (Builtin.Int64, Builtin.Int64, @thin SomeStruct.Type) -> SomeStruct
var st = SomeStruct(x: i, y: j)
// -- Use of unapplied struct methods as values.
// CHECK: [[THUNK:%.*]] = function_ref @_TFV9functions10SomeStruct6method{{.*}}
// CHECK: [[THUNK_THICK:%.*]] = thin_to_thick_function [[THUNK]]
var stm1 = SomeStruct.method
stm1(&st)(i)
// -- Curry 'self' onto method argument lists dispatched using class_method.
// CHECK: [[CBOX:%[0-9]+]] = alloc_box $SomeClass
// CHECK: [[CADDR:%.*]] = project_box [[CBOX]]
// CHECK: [[FUNC:%[0-9]+]] = function_ref @_TFC9functions9SomeClassC{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, @thick SomeClass.Type) -> @owned SomeClass
// CHECK: [[META:%[0-9]+]] = metatype $@thick SomeClass.Type
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: [[C:%[0-9]+]] = apply [[FUNC]]([[I]], [[J]], [[META]])
var c = SomeClass(x: i, y: j)
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[METHOD:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.method!1
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: apply [[METHOD]]([[I]], [[C]])
c.method(i)
// -- Curry 'self' onto unapplied methods dispatched using class_method.
// CHECK: [[METHOD_CURRY_THUNK:%.*]] = function_ref @_TFC9functions9SomeClass6method{{.*}}
// CHECK: apply [[METHOD_CURRY_THUNK]]
var cm1 = SomeClass.method(c)
cm1(i)
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[METHOD:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.method!1
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: apply [[METHOD]]([[I]], [[C]])
SomeClass.method(c)(i)
// -- Curry the Type onto static method argument lists.
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[METHOD:%[0-9]+]] = class_method [[META:%[0-9]+]] : {{.*}}, #SomeClass.static_method!1
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: apply [[METHOD]]([[I]], [[META]])
c.dynamicType.static_method(i)
// -- Curry property accesses.
// -- FIXME: class_method-ify class getters.
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[GETTER:%[0-9]+]] = class_method {{.*}} : $SomeClass, #SomeClass.someProperty!getter.1
// CHECK: apply [[GETTER]]([[C]])
i = c.someProperty
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.someProperty!setter.1 : (SomeClass) -> (Builtin.Int64) -> ()
// CHECK: apply [[SETTER]]([[I]], [[C]])
c.someProperty = i
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: [[K:%[0-9]+]] = load [[KADDR]]
// CHECK: [[GETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!getter.1 : (SomeClass) -> (Builtin.Int64, Builtin.Int64) -> Builtin.Int64 , $@convention(method) (Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> Builtin.Int64
// CHECK: apply [[GETTER]]([[J]], [[K]], [[C]])
i = c[j, k]
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: [[K:%[0-9]+]] = load [[KADDR]]
// CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!setter.1 : (SomeClass) -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) -> () , $@convention(method) (Builtin.Int64, Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> ()
// CHECK: apply [[SETTER]]([[K]], [[I]], [[J]], [[C]])
c[i, j] = k
// -- Curry the projected concrete value in an existential (or its Type)
// -- onto protocol type methods dispatched using protocol_method.
// CHECK: [[PBOX:%[0-9]+]] = alloc_box $SomeProtocol
// CHECK: [[PADDR:%.*]] = project_box [[PBOX]]
var p : SomeProtocol = ConformsToSomeProtocol()
// CHECK: [[TEMP:%.*]] = alloc_stack $SomeProtocol
// CHECK: copy_addr [[PADDR]] to [initialization] [[TEMP]]
// CHECK: [[PVALUE:%[0-9]+]] = open_existential_addr [[TEMP]] : $*SomeProtocol to $*[[OPENED:@opened(.*) SomeProtocol]]
// CHECK: [[PMETHOD:%[0-9]+]] = witness_method $[[OPENED]], #SomeProtocol.method!1
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: apply [[PMETHOD]]<[[OPENED]]>([[I]], [[PVALUE]])
// CHECK: destroy_addr [[PVALUE]]
// CHECK: deinit_existential_addr [[TEMP]]
// CHECK: dealloc_stack [[TEMP]]
p.method(i)
// CHECK: [[PVALUE:%[0-9]+]] = open_existential_addr [[PADDR:%.*]] : $*SomeProtocol to $*[[OPENED:@opened(.*) SomeProtocol]]
// CHECK: [[PMETHOD:%[0-9]+]] = witness_method $[[OPENED]], #SomeProtocol.method!1
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: apply [[PMETHOD]]<[[OPENED]]>([[I]], [[PVALUE]])
var sp : SomeProtocol = ConformsToSomeProtocol()
sp.method(i)
// FIXME: [[PMETHOD:%[0-9]+]] = witness_method $[[OPENED:@opened(.*) SomeProtocol]], #SomeProtocol.static_method!1
// FIXME: [[I:%[0-9]+]] = load [[IADDR]]
// FIXME: apply [[PMETHOD]]([[I]], [[PMETA]])
// Needs existential metatypes
//p.dynamicType.static_method(i)
// -- Use an apply or partial_apply instruction to bind type parameters of a generic.
// CHECK: [[GBOX:%[0-9]+]] = alloc_box $SomeGeneric<Builtin.Int64>
// CHECK: [[GADDR:%.*]] = project_box [[GBOX]]
// CHECK: [[CTOR_GEN:%[0-9]+]] = function_ref @_TFC9functions11SomeGenericC{{.*}} : $@convention(thin) <τ_0_0> (@thick SomeGeneric<τ_0_0>.Type) -> @owned SomeGeneric<τ_0_0>
// CHECK: [[META:%[0-9]+]] = metatype $@thick SomeGeneric<Builtin.Int64>.Type
// CHECK: apply [[CTOR_GEN]]<Builtin.Int64>([[META]])
var g = SomeGeneric<Builtin.Int64>()
// CHECK: [[G:%[0-9]+]] = load [[GADDR]]
// CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[G]] : {{.*}}, #SomeGeneric.method!1
// CHECK: [[TMPI:%.*]] = alloc_stack $Builtin.Int64
// CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64
// CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPI]], [[G]])
g.method(i)
// CHECK: [[G:%[0-9]+]] = load [[GADDR]]
// CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[G]] : {{.*}}, #SomeGeneric.generic!1
// CHECK: [[TMPJ:%.*]] = alloc_stack $Builtin.Int64
// CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64
// CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPJ]], [[G]])
g.generic(j)
// CHECK: [[C:%[0-9]+]] = load [[CADDR]]
// CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.generic!1
// CHECK: [[TMPK:%.*]] = alloc_stack $Builtin.Int64
// CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64
// CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPK]], [[C]])
c.generic(k)
// FIXME: curried generic entry points
//var gm1 = g.method
//gm1(i)
//var gg1 : (Int) -> Int = g.generic
//gg1(j)
//var cg1 : (Int) -> Int = c.generic
//cg1(k)
// SIL-level "thin" function values need to be able to convert to
// "thick" function values when stored, returned, or passed as arguments.
// CHECK: [[FBOX:%[0-9]+]] = alloc_box $@callee_owned (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[FADDR:%.*]] = project_box [[FBOX]]
// CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @_TF9functions19standalone_function{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[FUNC_THICK:%[0-9]+]] = thin_to_thick_function [[FUNC_THIN]]
// CHECK: store [[FUNC_THICK]] to [[FADDR]]
var f = standalone_function
// CHECK: [[F:%[0-9]+]] = load [[FADDR]]
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: apply [[F]]([[I]], [[J]])
f(i, j)
// CHECK: [[HOF:%[0-9]+]] = function_ref @_TF9functions21higher_order_function{{.*}} : $@convention(thin) {{.*}}
// CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @_TF9functions19standalone_function{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[FUNC_THICK:%[0-9]+]] = thin_to_thick_function [[FUNC_THIN]]
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: apply [[HOF]]([[FUNC_THICK]], [[I]], [[J]])
higher_order_function(standalone_function, i, j)
// CHECK: [[HOF2:%[0-9]+]] = function_ref @_TF9functions22higher_order_function2{{.*}} : $@convention(thin) {{.*}}
// CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @_TF9functions19standalone_function{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[FUNC_THICK:%.*]] = thin_to_thick_function [[FUNC_THIN]]
// CHECK: [[I:%[0-9]+]] = load [[IADDR]]
// CHECK: [[J:%[0-9]+]] = load [[JADDR]]
// CHECK: apply [[HOF2]]([[FUNC_THICK]], [[I]], [[J]])
higher_order_function2(standalone_function, i, j)
}
// -- Curried entry points
// CHECK-LABEL: sil shared @_TFV9functions10SomeStruct6method{{.*}} : $@convention(thin) (@inout SomeStruct) -> @owned @callee_owned (Builtin.Int64) -> () {
// CHECK: [[UNCURRIED:%.*]] = function_ref @_TFV9functions10SomeStruct6method{{.*}} : $@convention(method) (Builtin.Int64, @inout SomeStruct) -> (){{.*}} // user: %2
// CHECK: [[CURRIED:%.*]] = partial_apply [[UNCURRIED]]
// CHECK: return [[CURRIED]]
// CHECK-LABEL: sil shared @_TFC9functions9SomeClass6method{{.*}} : $@convention(thin) (@owned SomeClass) -> @owned @callee_owned (Builtin.Int64) -> ()
// CHECK: bb0(%0 : $SomeClass):
// CHECK: class_method %0 : $SomeClass, #SomeClass.method!1 : (SomeClass) -> (Builtin.Int64) -> ()
// CHECK: %2 = partial_apply %1(%0)
// CHECK: return %2
func return_func() -> (x: Builtin.Int64, y: Builtin.Int64) -> Builtin.Int64 {
// CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @_TF9functions19standalone_function{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
// CHECK: [[FUNC_THICK:%[0-9]+]] = thin_to_thick_function [[FUNC_THIN]]
// CHECK: return [[FUNC_THICK]]
return standalone_function
}
func standalone_generic<T>(x: T, y: T) -> T { return x }
// CHECK-LABEL: sil hidden @_TF9functions14return_genericFT_FT1xBi64_1yBi64__Bi64_
func return_generic() -> (x:Builtin.Int64, y:Builtin.Int64) -> Builtin.Int64 {
// CHECK: [[GEN:%.*]] = function_ref @_TF9functions18standalone_generic{{.*}} : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> @out τ_0_0
// CHECK: [[SPEC:%.*]] = partial_apply [[GEN]]<Builtin.Int64>()
// CHECK: [[THUNK:%.*]] = function_ref @{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, @owned @callee_owned (@in Builtin.Int64, @in Builtin.Int64) -> @out Builtin.Int64) -> Builtin.Int64
// CHECK: [[T0:%.*]] = partial_apply [[THUNK]]([[SPEC]])
// CHECK: return [[T0]]
return standalone_generic
}
// CHECK-LABEL: sil hidden @_TF9functions20return_generic_tuple{{.*}}
func return_generic_tuple()
-> (x: (Builtin.Int64, Builtin.Int64), y: (Builtin.Int64, Builtin.Int64)) -> (Builtin.Int64, Builtin.Int64) {
// CHECK: [[GEN:%.*]] = function_ref @_TF9functions18standalone_generic{{.*}} : $@convention(thin) <τ_0_0> (@in τ_0_0, @in τ_0_0) -> @out τ_0_0
// CHECK: [[SPEC:%.*]] = partial_apply [[GEN]]<(Builtin.Int64, Builtin.Int64)>()
// CHECK: [[THUNK:%.*]] = function_ref @{{.*}} : $@convention(thin) (Builtin.Int64, Builtin.Int64, Builtin.Int64, Builtin.Int64, @owned @callee_owned (@in (Builtin.Int64, Builtin.Int64), @in (Builtin.Int64, Builtin.Int64)) -> @out (Builtin.Int64, Builtin.Int64)) -> (Builtin.Int64, Builtin.Int64)
// CHECK: [[T0:%.*]] = partial_apply [[THUNK]]([[SPEC]])
// CHECK: return [[T0]]
return standalone_generic
}
// CHECK-LABEL: sil hidden @_TF9functions16testNoReturnAttrFT_T_ : $@convention(thin) @noreturn () -> ()
@noreturn func testNoReturnAttr() -> () {}
// CHECK-LABEL: sil hidden @_TF9functions20testNoReturnAttrPoly{{.*}} : $@convention(thin) @noreturn <T> (@in T) -> ()
@noreturn func testNoReturnAttrPoly<T>(x: T) -> () {}
// CHECK-LABEL: sil hidden @_TF9functions21testNoReturnAttrParam{{.*}} : $@convention(thin) (@owned @noreturn @callee_owned () -> ()) -> ()
func testNoReturnAttrParam(fptr: @noreturn () -> ()) -> () {}
// CHECK-LABEL: sil hidden [transparent] @_TF9functions15testTransparent{{.*}} : $@convention(thin) (Builtin.Int1) -> Builtin.Int1
@_transparent func testTransparent(x: Bool) -> Bool {
return x
}
// CHECK-LABEL: sil hidden @_TF9functions16applyTransparent{{.*}} : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 {
func applyTransparent(x: Bool) -> Bool {
// CHECK: [[FUNC:%[0-9]+]] = function_ref @_TF9functions15testTransparent{{.*}} : $@convention(thin) (Builtin.Int1) -> Builtin.Int1
// CHECK: apply [[FUNC]]({{%[0-9]+}}) : $@convention(thin) (Builtin.Int1) -> Builtin.Int1
return testTransparent(x)
}
// CHECK-LABEL: sil hidden [noinline] @_TF9functions15noinline_calleeFT_T_ : $@convention(thin) () -> ()
@inline(never)
func noinline_callee() {}
// CHECK-LABEL: sil hidden [always_inline] @_TF9functions20always_inline_calleeFT_T_ : $@convention(thin) () -> ()
@inline(__always)
func always_inline_callee() {}
protocol AlwaysInline {
func alwaysInlined()
}
// CHECK-LABEL: sil hidden [always_inline] @_TFV9functions19AlwaysInlinedMember13alwaysInlined{{.*}} : $@convention(method) (AlwaysInlinedMember) -> () {
// protocol witness for functions.AlwaysInline.alwaysInlined <A : functions.AlwaysInline>(functions.AlwaysInline.Self)() -> () in conformance functions.AlwaysInlinedMember : functions.AlwaysInline in functions
// CHECK-LABEL: sil hidden [transparent] [thunk] [always_inline] @_TTWV9functions19AlwaysInlinedMemberS_12AlwaysInlineS_FS1_13alwaysInlined{{.*}} : $@convention(witness_method) (@in_guaranteed AlwaysInlinedMember) -> () {
struct AlwaysInlinedMember : AlwaysInline {
@inline(__always)
func alwaysInlined() {}
}
// CHECK-LABEL: sil hidden [_semantics "foo"] @_TF9functions9semanticsFT_T_ : $@convention(thin) () -> ()
@_semantics("foo")
func semantics() {}
// <rdar://problem/17828355> curried final method on a class crashes in irgen
final class r17828355Class {
func method(x : Int) {
var a : r17828355Class
var fn = a.method // currying a final method.
}
}
// The curry thunk for the method should not include a class_method instruction.
// CHECK-LABEL: sil shared @_TFC9functions14r17828355Class6methodF
// CHECK: bb0(%0 : $r17828355Class):
// CHECK-NEXT: // function_ref functions.r17828355Class.method (Builtin.Int64) -> ()
// CHECK-NEXT: %1 = function_ref @_TFC9functions14r17828355Class6method{{.*}} : $@convention(method) (Builtin.Int64, @guaranteed r17828355Class) -> ()
// CHECK-NEXT: partial_apply %1(%0) : $@convention(method) (Builtin.Int64, @guaranteed r17828355Class) -> ()
// CHECK-NEXT: return
// <rdar://problem/19981118> Swift 1.2 beta 2: Closures nested in @noescape closures copy, rather than reference, captured vars.
func noescapefunc(@noescape f: () -> ()) {}
func escapefunc(f : () -> ()) {}
func testNoescape() {
// "a" must be captured by-box into noescapefunc because the inner closure
// could escape it.
var a = 0
noescapefunc {
escapefunc { a = 42 }
}
markUsed(a)
}
// CHECK-LABEL: functions.testNoescape () -> ()
// CHECK-NEXT: sil hidden @_TF9functions12testNoescapeFT_T_ : $@convention(thin) () -> ()
// CHECK: function_ref functions.(testNoescape () -> ()).(closure #1)
// CHECK-NEXT: function_ref @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> ()
// Despite being a noescape closure, this needs to capture 'a' by-box so it can
// be passed to the capturing closure.closure
// CHECK: functions.(testNoescape () -> ()).(closure #1)
// CHECK-NEXT: sil shared @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () {
func testNoescape2() {
// "a" must be captured by-box into noescapefunc because the inner closure
// could escape it. This also checks for when the outer closure captures it
// in a way that could be used with escape: the union of the two requirements
// doesn't allow a by-address capture.
var a = 0
noescapefunc {
escapefunc { a = 42 }
markUsed(a)
}
markUsed(a)
}
// CHECK-LABEL: sil hidden @_TF9functions13testNoescape2FT_T_ : $@convention(thin) () -> () {
// CHECK: // functions.(testNoescape2 () -> ()).(closure #1)
// CHECK-NEXT: sil shared @_TFF9functions13testNoescape2FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () {
// CHECK: // functions.(testNoescape2 () -> ()).(closure #1).(closure #1)
// CHECK-NEXT: sil shared @_TFFF9functions13testNoescape2FT_T_U_FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () {
enum PartialApplyEnumPayload<T, U> {
case Left(T)
case Right(U)
}
struct S {}
struct C {}
func partialApplyEnumCases(x: S, y: C) {
let left = PartialApplyEnumPayload<S, C>.Left
let left2 = left(S())
let right = PartialApplyEnumPayload<S, C>.Right
let right2 = right(C())
}
// CHECK-LABEL: sil shared [transparent] @_TFO9functions23PartialApplyEnumPayload4Left{{.*}}
// CHECK: [[UNCURRIED:%.*]] = function_ref @_TFO9functions23PartialApplyEnumPayload4Left{{.*}}
// CHECK: [[CLOSURE:%.*]] = partial_apply [[UNCURRIED]]<T, U>(%0)
// CHECK: return [[CLOSURE]]
// CHECK-LABEL: sil shared [transparent] @_TFO9functions23PartialApplyEnumPayload5Right{{.*}}
// CHECK: [[UNCURRIED:%.*]] = function_ref @_TFO9functions23PartialApplyEnumPayload5Right{{.*}}
// CHECK: [[CLOSURE:%.*]] = partial_apply [[UNCURRIED]]<T, U>(%0)
// CHECK: return [[CLOSURE]]