Files
swift-mirror/test/DebuggerTestingTransform/basic-assignments.swift
Vedant Kumar ca27e829ba Add a transform to help test lldb expression evaluation
The initial version of the debugger testing transform instruments
assignments in a way that allows the debugger to sanity-check its
expression evaluator.

Given an assignment expression of the form:

```
  a = b
```

The transform rewrites the relevant bits of the AST to look like this:

```
  { () -> () in
    a = b
    checkExpect("a", stringForPrintObject(a))
  }()
```

The purpose of the rewrite is to make it easier to exercise the
debugger's expression evaluator in new contexts. This can be automated
by having the debugger set a breakpoint on checkExpect, running `expr
$Varname`, and comparing the result to the expected value generated by
the runtime.

While the initial version of this testing transform only supports
instrumenting assignments, it should be simple to teach it to do more
interesting rewrites.

There's a driver script available in SWIFT_BIN_DIR/lldb-check-expect to
simplfiy the process of launching and testing instrumented programs.

rdar://36032055
2018-03-30 16:50:31 -07:00

88 lines
2.6 KiB
Swift

// RUN: %target-swift-frontend -debugger-testing-transform -Xllvm -sil-full-demangle -emit-sil -module-name M %s | %FileCheck %s -check-prefix=CHECK-SIL
// REQUIRES: executable_test
// RUN: %target-build-swift -Xfrontend -debugger-testing-transform %s -o %t
// RUN: %target-run %t | %FileCheck %s -check-prefix=CHECK-E2E
// RUN: rm -rf %t
var a = 1001
a = 1002
// CHECK-SIL-LABEL: sil private @$S1MyyXEfU0_ : {{.*}} () -> ()
// CHECK-SIL: [[int:%.*]] = integer_literal {{.*}}, 1002
// CHECK-SIL: [[struct:%.*]] = struct $Int ([[int]] : {{.*}})
// CHECK-SIL: store [[struct]] {{.*}} : $*Int
// CHECK-SIL: string_literal utf8 "a"
// CHECK-SIL: [[PO:%.*]] = function_ref {{.*}}_stringForPrintObjectySSypF
// CHECK-SIL: [[PO_result:%.*]] = apply [[PO]]
// CHECK-SIL: [[check_expect:%.*]] = function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
// CHECK-SIL: apply [[check_expect]]
print("a = \(a)") // CHECK-E2E: a = 1002
// CHECK-SIL-LABEL: sil private @$S1MyyXEfU_yyXEfU1_
({ () -> () in
a = 1003
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
print("a = \(a)") // CHECK-E2E-NEXT: a = 1003
})()
// CHECK-SIL-LABEL: sil private @$S1MyyXEfU2_
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
a = 1004
print("a = \(a)") // CHECK-E2E-NEXT: a = 1004
// CHECK-SIL-LABEL: sil private @$S1M2f1yyFyyXEfU3_
func f1() {
var b = 2001
b = 2002
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
print("b = \(b)") // CHECK-E2E-NEXT: b = 2002
}
f1()
// CHECK-SIL-LABEL: sil private @$S1M2f2yyFyyXEfU_yyXEfU4_
func f2() {
var c: Int = 3001
({ () -> () in
c = 3002
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
print("c = \(c)") // CHECK-E2E-NEXT: c = 3002
})()
}
f2()
// CHECK-SIL-LABEL: sil private @$S1M2f3yySaySiGzFyyXEfU5_
func f3(_ d: inout [Int]) {
d[0] = 4002
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
print("d[0] = \(d[0])") // CHECK-E2E-NEXT: d[0] = 4002
}
var d: [Int] = [4001]
f3(&d)
// CHECK-SIL-LABEL: sil hidden @$S1M2f4yyF
// CHECK-SIL-NOT: _debuggerTestingCheckExpect
func f4() {
// We don't attempt to instrument in this case because we don't try
// to prove that the var decl is definitively initialized.
var e: Int
e = 5001
print("e = \(e)") // CHECK-E2E-NEXT: e = 5001
}
f4()
// CHECK-SIL-LABEL: sil private @$S1M2f5yySSzFyyXEfU6_
func f5(_ v: inout String) {
v = "Hello world"
// CHECK-SIL: function_ref {{.*}}_debuggerTestingCheckExpectyySS_SStF
print("v = \(v)") // CHECK-E2E-NEXT: v = Hello world
}
var v: String = ""
f5(&v)