Raw File
recursive_func.sil
// RUN: %target-swift-frontend -O %s  -emit-sil | FileCheck %s

// rdar://16761933
// Make sure we can handle recursive function within a class.

// CHECK-LABEL: @main
// CHECK: function_ref @REC_recursive

sil_stage raw

import Builtin
import Swift

class REC {
  func recursive(a: Int)
}

sil @main : $@convention(c) (Builtin.Int32, Builtin.RawPointer) -> Builtin.Int32 {
bb0(%c : $Builtin.Int32, %v : $Builtin.RawPointer):
  // function_ref test.test (Swift.Int) -> ()
  %0 = function_ref @_TF4test4testFSiT_ : $@convention(thin) (Int) -> () // user: %5
  // function_ref Swift.Int._convertFromBuiltinIntegerLiteral (Swift.Int.Type)(Builtin.Int2048) -> Swift.Int
  %1 = function_ref @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %4
  %2 = metatype $@thin Int.Type                   // user: %4
  %3 = integer_literal $Builtin.Int2048, 1000     // user: %4
  %4 = apply %1(%3, %2) : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %5
  %5 = apply %0(%4) : $@convention(thin) (Int) -> ()
  %6 = integer_literal $Builtin.Int32, 0
  return %6 : $Builtin.Int32
}

sil @REC_recursive : $@convention(method) (Int, @guaranteed REC) -> () {
bb0(%0 : $Int, %1 : $REC):
  debug_value %0 : $Int, let, name "a" // id: %2
  debug_value %1 : $REC, let, name "self" // id: %3
  // function_ref Swift.Bool._getBuiltinLogicValue (Swift.Bool)() -> Builtin.Int1
  %4 = function_ref @_TFSb21_getBuiltinLogicValuefSbFT_Bi1_ : $@convention(method) (Bool) -> Builtin.Int1 // user: %11
  // function_ref Swift.>= @infix (Swift.Int, Swift.Int) -> Swift.Bool
  %5 = function_ref @_TFsoi2geFTSiSi_Sb : $@convention(thin) (Int, Int) -> Bool // user: %10
  // function_ref Swift.Int._convertFromBuiltinIntegerLiteral (Swift.Int.Type)(Builtin.Int2048) -> Swift.Int
  %6 = function_ref @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %9
  %7 = metatype $@thin Int.Type                   // user: %9
  %8 = integer_literal $Builtin.Int2048, 2        // user: %9
  %9 = apply %6(%8, %7) : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %10
  %10 = apply %5(%0, %9) : $@convention(thin) (Int, Int) -> Bool // user: %11
  %11 = apply %4(%10) : $@convention(method) (Bool) -> Builtin.Int1 // user: %12
  cond_br %11, bb1, bb2                           // id: %12

bb1:                                              // Preds: bb0
  strong_retain %1 : $REC                         // id: %13
  %14 = class_method %1 : $REC, #REC.recursive!1 : REC -> (Int) -> () , $@convention(method) (Int, @guaranteed REC) -> () // user: %21
  // function_ref Swift.- @infix (Swift.Int, Swift.Int) -> Swift.Int
  %15 = function_ref @_TFsoi1sFTSiSi_Si : $@convention(thin) (Int, Int) -> Int // user: %20
  // function_ref Swift.Int._convertFromBuiltinIntegerLiteral (Swift.Int.Type)(Builtin.Int2048) -> Swift.Int
  %16 = function_ref @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %19
  %17 = metatype $@thin Int.Type                  // user: %19
  %18 = integer_literal $Builtin.Int2048, 2       // user: %19
  %19 = apply %16(%18, %17) : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %20
  %20 = apply %15(%0, %19) : $@convention(thin) (Int, Int) -> Int // user: %21
  %21 = apply %14(%20, %1) : $@convention(method) (Int, @guaranteed REC) -> ()
  strong_retain %1 : $REC                         // id: %22
  %23 = class_method %1 : $REC, #REC.recursive!1 : REC -> (Int) -> () , $@convention(method) (Int, @guaranteed REC) -> () // user: %30
  // function_ref Swift.- @infix (Swift.Int, Swift.Int) -> Swift.Int
  %24 = function_ref @_TFsoi1sFTSiSi_Si : $@convention(thin) (Int, Int) -> Int // user: %29
  // function_ref Swift.Int._convertFromBuiltinIntegerLiteral (Swift.Int.Type)(Builtin.Int2048) -> Swift.Int
  %25 = function_ref @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %28
  %26 = metatype $@thin Int.Type                  // user: %28
  %27 = integer_literal $Builtin.Int2048, 1       // user: %28
  %28 = apply %25(%27, %26) : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int // user: %29
  %29 = apply %24(%0, %28) : $@convention(thin) (Int, Int) -> Int // user: %30
  %30 = apply %23(%29, %1) : $@convention(method) (Int, @guaranteed REC) -> ()
  br bb2                                          // id: %31

bb2:                                              // Preds: bb0 bb1
  strong_release %1 : $REC                        // id: %32
  %33 = tuple ()                                  // user: %34
  return %33 : $()                                // id: %34
}

// Swift.Bool._getBuiltinLogicValue (Swift.Bool)() -> Builtin.Int1
sil [transparent] @_TFSb21_getBuiltinLogicValuefSbFT_Bi1_ : $@convention(method) (Bool) -> Builtin.Int1

// Swift.>= @infix (Swift.Int, Swift.Int) -> Swift.Bool
sil [transparent] @_TFsoi2geFTSiSi_Sb : $@convention(thin) (Int, Int) -> Bool

// Swift.Int._convertFromBuiltinIntegerLiteral (Swift.Int.Type)(Builtin.Int2048) -> Swift.Int
sil [transparent] @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int

// Swift.- @infix (Swift.Int, Swift.Int) -> Swift.Int
sil [transparent] @_TFsoi1sFTSiSi_Si : $@convention(thin) (Int, Int) -> Int

// test.REC.deinit
sil @_TFC4test3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject {
bb0(%0 : $REC):
  debug_value %0 : $REC, let, name "self" // id: %1
  %2 = unchecked_ref_cast %0 : $REC to $Builtin.NativeObject // user: %3
  return %2 : $Builtin.NativeObject               // id: %3
}

// test.REC.__deallocating_deinit
sil @_TFC4test3RECD : $@convention(method) (@owned REC) -> () {
bb0(%0 : $REC):
  debug_value %0 : $REC, let, name "self" // id: %1
  // function_ref test.REC.deinit
  %2 = function_ref @_TFC4test3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %3
  %3 = apply %2(%0) : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %4
  %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $REC // user: %5
  dealloc_ref %4 : $REC                           // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
}

// test.REC.init (test.REC.Type)() -> test.REC
sil @_TFC4test3RECcfMS0_FT_S0_ : $@convention(method) (@owned REC) -> @owned REC {
bb0(%0 : $REC):
  debug_value %0 : $REC, let, name "self" // id: %1
  %2 = mark_uninitialized [rootself] %0 : $REC    // user: %3
  return %2 : $REC                                // id: %3
}

// test.REC.__allocating_init (test.REC.Type)() -> test.REC
sil @_TFC4test3RECCfMS0_FT_S0_ : $@convention(thin) (@thick REC.Type) -> @owned REC {
bb0(%0 : $@thick REC.Type):
  %1 = alloc_ref $REC                             // user: %3
  // function_ref test.REC.init (test.REC.Type)() -> test.REC
  %2 = function_ref @_TFC4test3RECcfMS0_FT_S0_ : $@convention(method) (@owned REC) -> @owned REC // user: %3
  %3 = apply %2(%1) : $@convention(method) (@owned REC) -> @owned REC // user: %4
  return %3 : $REC                                // id: %4
}

// test.test (Swift.Int) -> ()
sil @_TF4test4testFSiT_ : $@convention(thin) (Int) -> () {
bb0(%0 : $Int):
  debug_value %0 : $Int, let, name "N" // id: %1
  // function_ref test.REC.__allocating_init (test.REC.Type)() -> test.REC
  %2 = function_ref @_TFC4test3RECCfMS0_FT_S0_ : $@convention(thin) (@thick REC.Type) -> @owned REC // user: %4
  %3 = metatype $@thick REC.Type                  // user: %4
  %4 = apply %2(%3) : $@convention(thin) (@thick REC.Type) -> @owned REC // users: %5, %6, %7, %8, %9
  debug_value %4 : $REC, let, name "rec" // id: %5
  strong_retain %4 : $REC                         // id: %6
  %7 = class_method %4 : $REC, #REC.recursive!1 : REC -> (Int) -> () , $@convention(method) (Int, @guaranteed REC) -> () // user: %8
  %8 = apply %7(%0, %4) : $@convention(method) (Int, @guaranteed REC) -> ()
  strong_release %4 : $REC                        // id: %9
  %10 = tuple ()                                  // user: %11
  return %10 : $()                                // id: %11
}

sil_vtable REC {
  #REC.recursive!1: REC_recursive	// test.REC.recursive (test.REC)(Swift.Int) -> ()
  #REC.init!initializer.1: _TFC4test3RECcfMS0_FT_S0_	// test.REC.init (test.REC.Type)() -> test.REC
}
back to top