Files
swift-mirror/test/DebugInfo/patternmatching.swift
Adrian Prantl 053d7cf277 Debug Info: Don't emit shadow stack copies for local variables.
The effect of this tiny change is that local variables will be described
by llvm.dbg.values, which will get lowered into an accurate location list
instead of a stack slot that is valid for the entire scope of the variable.
This means the debugger can now accurately track the liveness of variables
knowing exactly when they are initialized and when there values go away.
Function arguments are still kept in stack slots because (1) they are
already initialized at the function entry and (2) LLDB really needs self
to be available at all times for the expression evaluator.

This was made possible by recent advancements in LLVM such as the live
debug variables pass and various related bugfixes.

<rdar://problem/15746520>
2016-03-08 11:10:02 -08:00

60 lines
3.0 KiB
Swift

// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o %t.ll
// RUN: FileCheck %s < %t.ll
// RUN: FileCheck --check-prefix=CHECK-SCOPES %s < %t.ll
// RUN: %target-swift-frontend -emit-sil -emit-verbose-sil -primary-file %s -o - | FileCheck %s --check-prefix=SIL-CHECK
func markUsed<T>(t: T) {}
func classifyPoint2(p: (Double, Double)) {
func return_same (input : Double) -> Double
{
return input; // return_same gets called in both where statements
}
switch p {
case (let x, let y) where
// CHECK: call double {{.*}}return_same{{.*}}, !dbg ![[LOC1:.*]]
// CHECK: br {{.*}}, label {{.*}}, label {{.*}}, !dbg ![[LOC2:.*]]
// CHECK: call{{.*}}markUsed{{.*}}, !dbg ![[LOC3:.*]]
// CHECK: ![[LOC1]] = !DILocation(line: [[@LINE+2]],
// CHECK: ![[LOC2]] = !DILocation(line: [[@LINE+1]],
return_same(x) == return_same(y):
// CHECK: ![[LOC3]] = !DILocation(line: [[@LINE+1]],
markUsed(x)
// SIL-CHECK: dealloc_stack{{.*}}line:[[@LINE-1]]:17:cleanup
// Verify that the branch has a location >= the cleanup.
// SIL-CHECK-NEXT: br{{.*}}line:[[@LINE-3]]:17:cleanup
// CHECK-SCOPES: call {{.*}}markUsed
// CHECK-SCOPES: call void @llvm.dbg.value({{.*}}metadata ![[X1:[0-9]+]]
// CHECK-SCOPES-SAME: !dbg ![[X1LOC:[0-9]+]]
// CHECK-SCOPES: call void @llvm.dbg.value
// CHECK-SCOPES: call void @llvm.dbg.value({{.*}}metadata ![[X2:[0-9]+]]
// CHECK-SCOPES-SAME: !dbg ![[X2LOC:[0-9]+]]
// CHECK-SCOPES: call void @llvm.dbg.value
// CHECK-SCOPES: call void @llvm.dbg.value({{.*}}metadata ![[X3:[0-9]+]]
// CHECK-SCOPES-SAME: !dbg ![[X3LOC:[0-9]+]]
// CHECK-SCOPES: !DILocalVariable(name: "x",
case (let x, let y) where x == -y:
// Verify that all variables end up in separate appropriate scopes.
// CHECK-SCOPES: !DILocalVariable(name: "x", scope: ![[SCOPE1:[0-9]+]],
// CHECK-SCOPES-SAME: line: [[@LINE-3]]
// CHECK-SCOPES: ![[X1LOC]] = !DILocation(line: [[@LINE-4]], column: 15,
// CHECK-SCOPES-SAME: scope: ![[SCOPE1]])
// FIXME: ![[SCOPE1]] = distinct !DILexicalBlock({{.*}}line: [[@LINE-6]]
markUsed(x)
case (let x, let y) where x >= -10 && x < 10 && y >= -10 && y < 10:
// CHECK-SCOPES: !DILocalVariable(name: "x", scope: ![[SCOPE2:[0-9]+]],
// CHECK-SCOPES-SAME: line: [[@LINE-2]]
// CHECK-SCOPES: ![[X2LOC]] = !DILocation(line: [[@LINE-3]], column: 15,
// CHECK-SCOPES-SAME: scope: ![[SCOPE2]])
markUsed(x)
case (let x, let y):
// CHECK-SCOPES: !DILocalVariable(name: "x", scope: ![[SCOPE3:[0-9]+]],
// CHECK-SCOPES-SAME: line: [[@LINE-2]]
// CHECK-SCOPES: ![[X3LOC]] = !DILocation(line: [[@LINE-3]], column: 15,
// CHECK-SCOPES-SAME: scope: ![[SCOPE3]])
markUsed(x)
}
// CHECK: !DILocation(line: [[@LINE+1]],
}