File: inline_self.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (97 lines) | stat: -rw-r--r-- 2,637 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -O -emit-sil  -primary-file %s | %FileCheck %s
//
// This is a .swift test because the SIL parser does not support Self.

// Do not inline C.factory into main. Doing so would lose the ability
// to materialize local Self metadata.

// REQUIRES: swift_in_compiler

class C {
  required init() {}
}

class SubC : C {}

var g: AnyObject = SubC()

@inline(never)
func gen<R>() -> R {
  return g as! R
}

extension C {
  @inline(__always)
  class func factory(_ z: Int) -> Self {
    return gen()
  }
}

// Call the function so it can be inlined.
var x = C()
var x2 = C.factory(1)

@inline(never)
func callIt(fn: () -> ()) {
  fn()
}

protocol Use {
  func use<T>(_ t: T)
}

var user: Use? = nil

class BaseZ {
  final func baseCapturesSelf() -> Self {
    let fn = { [weak self] in _ = self }
    callIt(fn: fn)
    return self
  }
}

// Do not inline C.capturesSelf() into main either. Doing so would lose the ability
// to materialize local Self metadata.
class Z : BaseZ {
  @inline(__always)
  final func capturesSelf() -> Self {
    let fn = { [weak self] in _ = self }
    callIt(fn: fn)
    user?.use(self)
    return self
  }

  // Inline captureSelf into callCaptureSelf,
  // because their respective Self types refer to the same type.
  final func callCapturesSelf() -> Self {
    return capturesSelf()
  }

  final func callBaseCapturesSelf() -> Self {
    return baseCapturesSelf()
  }
}

_ = Z().capturesSelf()

// CHECK-LABEL: sil {{.*}}@main : $@convention(c)
// CHECK: function_ref static inline_self.C.factory(Swift.Int) -> Self
// CHECK: [[F:%[0-9]+]] = function_ref @$s11inline_self1CC7factory{{[_0-9a-zA-Z]*}}FZ : $@convention(method) (Int, @thick C.Type) -> @owned C
// CHECK: apply [[F]](%{{.+}}, %{{.+}}) : $@convention(method) (Int, @thick C.Type) -> @owned C

// CHECK: [[Z:%.*]] = alloc_ref $Z
// CHECK: [[C:%.*]] = upcast [[Z]]
// CHECK: [[EI:%.*]] = end_init_let_ref [[C]]
// CHECK: [[DC:%.*]] = unchecked_ref_cast [[EI]]
// CHECK: function_ref inline_self.Z.capturesSelf() -> Self
// CHECK: [[F:%[0-9]+]] = function_ref @$s11inline_self1ZC12capturesSelfACXDyF : $@convention(method) (@guaranteed Z) -> @owned Z
// CHECK: apply [[F]]([[DC]]) : $@convention(method) (@guaranteed Z) -> @owned
// CHECK: return

// CHECK-LABEL: sil hidden @$s11inline_self1ZC16callCapturesSelfACXDyF : $@convention(method)
// CHECK-NOT: function_ref @$s11inline_self1ZC12capturesSelfACXDyF :
// CHECK: }

// CHECK-LABEL: sil hidden {{.*}}@$s11inline_self1ZC20callBaseCapturesSelfACXDyF
// CHECK-NOT: function_ref @$s11inline_self5BaseZC16baseCapturesSelfACXDyF :
// CHECK: }