10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
//
13
- // TO ADD A NEW TEST, just add a new FunctionTest instance.
13
+ // TO ADD A NEW TEST, just add a new Test instance.
14
14
// - In the source file containing the functionality you want to test:
15
- // let myNewTest =
16
- // FunctionTest("my_new_test") { function, arguments, context in
15
+ // let myNewTest = Test("my_new_test") { function, arguments, context in
17
16
// }
18
- // - In SwiftCompilerSources/Sources/SIL/Test.swift's registerOptimizerTests
17
+ // - In SwiftCompilerSources/Sources/SIL/Test.swift's registerTests
19
18
// function, add a new argument to the variadic function:
20
- // registerFunctionTests(..., myNewTest)
21
- //
22
- //===----------------------------------------------------------------------===//
23
- //
24
- // TO TROUBLESHOOT A NEW TEST, consider the following scenarios:
25
- // - PROBLEM: The test isn't running on PLATFORM and the failure says
26
- //
27
- // Found no test named my_new_test.
28
- //
29
- // SOLUTION: Is this a platform one that doesn't use SwiftCompilerSources
30
- // (e.g. Windows)? Then add
31
- //
32
- // // REQUIRES: swift_in_compiler
33
- //
34
- // to the test file.
35
- // EXPLANATION: The tests written within SwiftCompilerSources only get built
36
- // and registered on platforms where the SwiftCompilerSources are
37
- // built and used.
19
+ // registerTests(..., myNewTest)
38
20
//
39
21
//===----------------------------------------------------------------------===//
40
22
//
41
23
// Provides a mechanism for writing tests against compiler code in the context
42
- // of a function. The goal is to get the same effect as calling a function and
24
+ // of a function. The goal is to get the same effect as calling a function and
43
25
// checking its output.
44
26
//
45
- // This is done via the specify_test instruction. Using one or more instances
27
+ // This is done via the specify_test instruction. Using one or more instances
46
28
// of it in your test case's SIL function, you can specify which test (instance
47
- // of FunctionTest) should be run and what arguments should be provided to it.
48
- // For full details of the specify_test instruction's grammar, see SIL.rst.
29
+ // of Test) should be run and what arguments should be provided to it.
30
+ // For full details of the specify_test instruction's grammar,
31
+ // see doc/SIL/Instructions.md.
49
32
//
50
33
// The test grabs the arguments it expects out of the TestArguments instance
51
34
// it is provided. It calls some function or functions. It then prints out
59
42
//
60
43
// and
61
44
//
62
- // let myNeatoUtilityTest =
63
- // FunctionTest("my_neato_utility") { function, arguments, test in
45
+ // let myNeatoUtilityTest = Test("my_neato_utility") { function, arguments, test in
64
46
// // The code here is described in detail below.
65
47
// // See 4).
66
48
// let count = arguments.takeInt()
82
64
// specify_test "my_neato_utility 43 %2 @function[other_fun]"
83
65
// ...
84
66
// }
85
- // 3) TestRunner finds the FunctionTest instance myNeatoUtilityTest registered
67
+ // 3) TestRunner finds the Test instance myNeatoUtilityTest registered
86
68
// under the name "my_neato_utility", and calls run() on it, passing the
87
- // passing first the function, last the FunctionTest instance, AND in the
69
+ // passing first the function, last the Test instance, AND in the
88
70
// middle, most importantly a TestArguments instance that contains
89
71
//
90
72
// (43 : Int, someValue : Value, other_fun : Function)
108
90
//===----------------------------------------------------------------------===//
109
91
110
92
import Basic
111
- import SIL
112
93
import SILBridging
113
- import OptimizerBridging
114
94
115
95
/// The primary interface to in-IR tests.
116
- struct FunctionTest {
96
+ public struct Test {
117
97
let name : String
118
- let invocation : FunctionTestInvocation
98
+ let invocation : TestInvocation
119
99
120
- public init ( _ name: String , invocation: @escaping FunctionTestInvocation ) {
100
+ public init ( _ name: String , invocation: @escaping TestInvocation ) {
121
101
self . name = name
122
102
self . invocation = invocation
123
103
}
124
104
}
125
105
126
- /// The type of the closure passed to a FunctionTest.
127
- typealias FunctionTestInvocation = @convention ( thin) ( Function , TestArguments , FunctionPassContext ) -> ( )
106
+ /// The type of the closure passed to a Test.
107
+ public typealias TestInvocation = @convention ( thin) ( Function , TestArguments , TestContext ) -> ( )
108
+
109
+
110
+ public struct TestContext : MutatingContext {
111
+ public let _bridged : BridgedContext
112
+ public let notifyInstructionChanged : ( Instruction ) -> ( ) = { inst in }
113
+
114
+ fileprivate init ( bridged: BridgedContext ) { self . _bridged = bridged}
115
+ }
128
116
129
117
/// Wraps the arguments specified in the specify_test instruction.
130
118
public struct TestArguments {
@@ -150,77 +138,55 @@ extension BridgedTestArguments {
150
138
}
151
139
152
140
/// Registration of each test in the SIL module.
153
- public func registerOptimizerTests ( ) {
141
+ public func registerTests ( ) {
154
142
// Register each test.
155
- registerFunctionTests (
156
- getAccessBaseTest,
157
- addressOwnershipLiveRangeTest,
158
- argumentConventionsTest,
159
- borrowIntroducersTest,
160
- enclosingValuesTest,
161
- forwardingDefUseTest,
162
- forwardingUseDefTest,
163
- getPullbackClosureInfoTest,
164
- interiorLivenessTest,
165
- lifetimeDependenceRootTest,
166
- lifetimeDependenceScopeTest,
167
- lifetimeDependenceUseTest,
168
- linearLivenessTest,
169
- localVariableReachableUsesTest,
170
- localVariableReachingAssignmentsTest,
171
- parseTestSpecificationTest,
172
- rangeOverlapsPathTest,
173
- rewrittenCallerBodyTest,
174
- specializedFunctionSignatureAndBodyTest,
175
- variableIntroducerTest
143
+ registerTests (
144
+ parseTestSpecificationTest
176
145
)
177
146
178
- // Finally register the thunk they all call through.
179
- registerFunctionTestThunk ( functionTestThunk)
147
+ registerTestThunk ( testThunk)
180
148
}
181
149
182
- private func registerFunctionTests ( _ tests: FunctionTest ... ) {
183
- tests. forEach { registerFunctionTest ( $0) }
150
+ private func registerTests ( _ tests: Test ... ) {
151
+ tests. forEach { registerTest ( $0) }
184
152
}
185
153
186
- private func registerFunctionTest ( _ test: FunctionTest ) {
154
+ private func registerTest ( _ test: Test ) {
187
155
test. name. _withBridgedStringRef { ref in
188
- registerFunctionTest ( ref, castToOpaquePointer ( fromInvocation: test. invocation) )
156
+ registerTest ( ref, castToOpaquePointer ( fromInvocation: test. invocation) )
189
157
}
190
158
}
191
159
192
160
/// The function called by the swift::test::FunctionTest which invokes the
193
161
/// actual test function.
194
162
///
195
163
/// This function is necessary because tests need to be written in terms of
196
- /// native Swift types (Function, TestArguments, BridgedPassContext )
164
+ /// native Swift types (Function, TestArguments, TestContext )
197
165
/// rather than their bridged variants, but such a function isn't representable
198
- /// in C++. This thunk unwraps the bridged types and invokes the real
199
- /// function.
200
- private func functionTestThunk(
166
+ /// in C++. This thunk unwraps the bridged types and invokes the real function.
167
+ private func testThunk(
201
168
_ erasedInvocation: UnsafeMutableRawPointer ,
202
- _ function: BridgedFunction ,
203
- _ arguments: BridgedTestArguments ,
169
+ _ function: BridgedFunction ,
170
+ _ arguments: BridgedTestArguments ,
204
171
_ bridgedContext: BridgedContext ) {
205
172
let invocation = castToInvocation ( fromOpaquePointer: erasedInvocation)
206
- let context = FunctionPassContext ( _bridged : bridgedContext)
173
+ let context = TestContext ( bridged : bridgedContext)
207
174
invocation ( function. function, arguments. native, context)
208
175
}
209
176
210
177
/// Bitcast a thin test closure to void *.
211
178
///
212
179
/// Needed so that the closure can be represented in C++ for storage in the test
213
180
/// registry.
214
- private func castToOpaquePointer( fromInvocation invocation: FunctionTestInvocation ) -> UnsafeMutableRawPointer {
181
+ private func castToOpaquePointer( fromInvocation invocation: TestInvocation ) -> UnsafeMutableRawPointer {
215
182
return unsafeBitCast ( invocation, to: UnsafeMutableRawPointer . self)
216
183
}
217
184
218
185
/// Bitcast a void * to a thin test closure.
219
186
///
220
- /// Needed so that the closure stored in the C++ test registry can be invoked
221
- /// via the functionTestThunk.
222
- private func castToInvocation( fromOpaquePointer erasedInvocation: UnsafeMutableRawPointer ) -> FunctionTestInvocation {
223
- return unsafeBitCast ( erasedInvocation, to: FunctionTestInvocation . self)
187
+ /// Needed so that the closure stored in the C++ test registry can be invoked via the testThunk.
188
+ private func castToInvocation( fromOpaquePointer erasedInvocation: UnsafeMutableRawPointer ) -> TestInvocation {
189
+ return unsafeBitCast ( erasedInvocation, to: TestInvocation . self)
224
190
}
225
191
226
192
// Arguments:
@@ -241,8 +207,7 @@ private func castToInvocation(fromOpaquePointer erasedInvocation: UnsafeMutableR
241
207
// - for each argument (after the initial string)
242
208
// - its type
243
209
// - something to identify the instance (mostly this means calling dump)
244
- let parseTestSpecificationTest =
245
- FunctionTest ( " test_specification_parsing " ) { function, arguments, context in
210
+ let parseTestSpecificationTest = Test ( " test_specification_parsing " ) { function, arguments, context in
246
211
let expectedFields = arguments. takeString ( )
247
212
for expectedField in expectedFields. string {
248
213
switch expectedField {
0 commit comments