File: witness_method.sil

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 (134 lines) | stat: -rw-r--r-- 6,228 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// RUN: %target-swift-frontend %s -emit-ir | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s -DINT=i%target-ptrsize

// REQUIRES: CPU=i386 || CPU=x86_64

sil_stage canonical

protocol DefCon {
  init()
}


// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @defcon(ptr noalias sret({{.*}}) %0, ptr %1, ptr %T, ptr %T.DefCon) {{.*}} {
sil @defcon : $@convention(thin) <T: DefCon> (@thick T.Type) -> @out T {
entry(%0: $*T, %1: $@thick T.Type):

  // CHECK-x86_64: [[WITNESS_GEP:%.*]] = getelementptr inbounds ptr, ptr %T.DefCon, i32 1
  // CHECK-i386: [[WITNESS_GEP:%.*]] = getelementptr inbounds ptr, ptr %T.DefCon, i32 1
  // CHECK-i386:   [[WITNESS:%.*]] = load ptr, ptr [[WITNESS_GEP]], align 4
  // CHECK-x86_64: [[WITNESS:%.*]] = load ptr, ptr [[WITNESS_GEP]], align 8
  // CHECK: call swiftcc void [[WITNESS]]
  %m = witness_method $T, #DefCon.init!allocator : $@convention(witness_method: DefCon) <U: DefCon> (@thick U.Type) -> @out U
  %z = apply %m<T>(%0, %1) : $@convention(witness_method: DefCon) <V: DefCon> (@thick V.Type) -> @out V
  return %z : $()
}

// rdar://24141848
protocol Base {
  func foo()
}
protocol Derived : Base {}
struct ImplementsDerived : Derived {
  func foo() {}
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testInheritedConformance
sil @testInheritedConformance : $@convention(thin) (@in ImplementsDerived) -> () {
entry(%0: $*ImplementsDerived):
  // CHECK: [[WITNESS:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @"$s14witness_method17ImplementsDerivedVAA4BaseAAWP", i32 1)
  // CHECK: call swiftcc void [[WITNESS]]
  %m = witness_method $ImplementsDerived, #Base.foo : $@convention(witness_method: Base) <U: Base> (@in_guaranteed U) -> ()
  %z = apply %m<ImplementsDerived>(%0) : $@convention(witness_method: Base) <V: Base> (@in_guaranteed V) -> ()
  return %z : $()
}


// Make sure a witness_method call with a generic Self type uses the correct
// calling convention.

protocol Synergy {
  associatedtype LowHangingFruit

  func actionItem() -> LowHangingFruit
}

struct SyncUp<Deliverable> : Synergy {
  let d: Deliverable

  func actionItem() -> Deliverable {
    return d
  }
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testGenericWitnessMethod(ptr noalias sret({{.*}}) %0, ptr noalias %1, ptr %T)
// CHECK: entry:
// CHECK:   [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s14witness_method6SyncUpVMa"([[INT]] 255, ptr %T)
// CHECK:   [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
// CHECK:   [[WTABLE:%.*]] = call ptr @swift_getWitnessTable(
// CHECK:   [[WITNESS_ADDR:%.*]] = getelementptr inbounds ptr, ptr [[WTABLE]], i32 2
// CHECK:   [[WITNESS_FN:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
// CHECK:   [[TMP:%.*]] = call swiftcc %swift.metadata_response @swift_checkMetadataState([[INT]] 0, ptr [[METADATA]])
// CHECK:   [[METADATA:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
// CHECK:   call swiftcc void [[WITNESS_FN]](ptr noalias sret({{.*}}) %0, ptr noalias swiftself %1, ptr [[METADATA]], ptr [[WTABLE]])
// CHECK:   ret void

sil @testGenericWitnessMethod : $@convention(thin) <T> (@in SyncUp<T>) -> @out T {
entry(%ret : $*T, %self : $*SyncUp<T>):
  %m = witness_method $SyncUp<T>, #Synergy.actionItem : $@convention(witness_method: Synergy) <U: Synergy> (@in_guaranteed U) -> @out U.LowHangingFruit
  %z = apply %m<SyncUp<T>>(%ret, %self) : $@convention(witness_method: Synergy) <U: Synergy> (@in_guaranteed U) -> @out U.LowHangingFruit
  return %z : $()
}

protocol Pivot {}

protocol Strategy {
  associatedtype GrowthHack : Pivot

  func disrupt() -> GrowthHack
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testArchetypeWitnessMethod(ptr noalias sret({{.*}}) %0, ptr noalias %1, ptr %T, ptr %T.Strategy)
// CHECK: entry:
// CHECK:   [[WITNESS_ADDR:%.*]] = getelementptr inbounds ptr, ptr %T.Strategy, i32 3
// CHECK:   [[WITNESS_FN:%.*]] = load ptr, ptr [[WITNESS_ADDR]]
// CHECK:   call swiftcc void [[WITNESS_FN]](ptr noalias sret({{.*}}) %0, ptr noalias swiftself %1, ptr %T, ptr %T.Strategy)
// CHECK:   ret void

sil @testArchetypeWitnessMethod : $@convention(thin) <T : Strategy> (@in T) -> @out T.GrowthHack {
entry(%ret : $*T.GrowthHack, %self : $*T):
  %m = witness_method $T, #Strategy.disrupt : $@convention(witness_method: Strategy) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
  %z = apply %m<T>(%ret, %self) : $@convention(witness_method: Strategy) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
  return %z : $()
}

// Class-constrained archetype witness method.
struct ToVideo : Pivot {}

class TPSReport<CoverSheet> : Strategy {
  typealias GrowthHack = ToVideo

  func disrupt() -> GrowthHack
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(ptr noalias nocapture swiftself dereferenceable({{4|8}}) %0, ptr %Self, ptr %SelfWitnessTable)

sil @classArchetypeWitnessMethod : $@convention(witness_method: Strategy) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> () {
entry(%self : $*T):
  %z = tuple ()
  return %z : $()
}

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testClassArchetypeWitnessMethod(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{4|8}}) %1, ptr %T, ptr %CoverSheet)
// CHECK: entry:
// CHECK:  [[WITNESS_FN:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @"$s14witness_method9TPSReportCyxGAA8StrategyAAWP", i32 3)
// CHECK: call swiftcc void [[WITNESS_FN]](ptr noalias sret({{.*}}) %0, ptr noalias swiftself %1, ptr %T, ptr @"$s14witness_method9TPSReportCyxGAA8StrategyAAWP")
// CHECK: ret void

sil @testClassArchetypeWitnessMethod : $@convention(thin) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> (@out T.GrowthHack) {
entry(%ret : $*T.GrowthHack, %self : $*T):
  %m = witness_method $T, #Strategy.disrupt : $@convention(witness_method: Strategy) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
  %z = apply %m<T>(%ret, %self) : $@convention(witness_method: Strategy) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
  return %z : $()
}

sil_vtable TPSReport {}