mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch replaces the stateful generation of SILScope information in SILGenFunction with data derived from the ASTScope hierarchy, which should be 100% in sync with the scopes needed for local variables. The goal is to eliminate the surprising effects that the stack of cleanup operations can have on the current state of SILBuilder leading to a fully deterministic (in the sense of: predictible by a human) association of SILDebugScopes with SILInstructions. The patch also eliminates the need to many workarounds. There are still some accomodations for several Sema transformation passes such as ResultBuilders, which don't correctly update the source locations when moving around nodes. If these were implemented as macros, this problem would disappear. This necessary rewrite of the macro scope handling included in this patch also adds proper support nested macro expansions. This fixes rdar://88274783 and either fixes or at least partially addresses the following: rdar://89252827 rdar://105186946 rdar://105757810 rdar://105997826 rdar://105102288
193 lines
6.7 KiB
Swift
193 lines
6.7 KiB
Swift
// RUN: %target-swift-frontend -enable-copy-propagation=requested-passes-only -enable-lexical-lifetimes=false -g -emit-ir %s -o %t.ll
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
|
|
// This file contains linetable testcases for all permutations
|
|
// of simple/complex/empty return expressions,
|
|
// cleanups/no cleanups, single / multiple return locations.
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_NONE < %t.ll
|
|
// CHECK_NONE: define{{( protected)?}} {{.*}}void {{.*}}none
|
|
public func none(_ a: inout Int64) {
|
|
// CHECK_NONE: call void @llvm.dbg{{.*}}, !dbg
|
|
// CHECK_NONE: store i64{{.*}}, !dbg ![[NONE_INIT:.*]]
|
|
a -= 2
|
|
// CHECK_NONE: ret {{.*}}, !dbg ![[NONE_RET:.*]]
|
|
// CHECK_NONE: ![[NONE_INIT]] = !DILocation(line: [[@LINE-2]], column:
|
|
// CHECK_NONE: ![[NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_EMPTY < %t.ll
|
|
// CHECK_EMPTY: define {{.*}}empty
|
|
public func empty(_ a: inout Int64) {
|
|
if a > 24 {
|
|
// CHECK-DAG_EMPTY: br {{.*}}, !dbg ![[EMPTY_RET1:.*]]
|
|
// CHECK-DAG_EMPTY_RET1: ![[EMPTY_RET1]] = !DILocation(line: [[@LINE+1]], column: 6,
|
|
return
|
|
}
|
|
|
|
a -= 2
|
|
// CHECK-DAG_EMPTY: br {{.*}}, !dbg ![[EMPTY_RET2:.*]]
|
|
// CHECK-DAG_EMPTY_RET2: ![[EMPTY_RET]] = !DILocation(line: [[@LINE+1]], column: 3,
|
|
return
|
|
// CHECK-DAG_EMPTY: ret {{.*}}, !dbg ![[EMPTY_RET:.*]]
|
|
// CHECK-DAG_EMPTY: ![[EMPTY_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_EMPTY_NONE < %t.ll
|
|
// CHECK_EMPTY_NONE: define {{.*}}empty_none
|
|
public func empty_none(_ a: inout Int64) {
|
|
if a > 24 {
|
|
return
|
|
}
|
|
|
|
a -= 2
|
|
// CHECK_EMPTY_NONE: ret {{.*}}, !dbg ![[EMPTY_NONE_RET:.*]]
|
|
// CHECK_EMPTY_NONE: ![[EMPTY_NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_SIMPLE_RET < %t.ll
|
|
// CHECK_SIMPLE_RET: define {{.*}}simple
|
|
public func simple(_ a: Int64) -> Int64 {
|
|
if a > 24 {
|
|
return 0
|
|
}
|
|
return 1
|
|
// CHECK_SIMPLE_RET: ret i{{.*}}, !dbg ![[SIMPLE_RET:.*]]
|
|
// CHECK_SIMPLE_RET: ![[SIMPLE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_COMPLEX_RET < %t.ll
|
|
// CHECK_COMPLEX_RET: define {{.*}}complex
|
|
public func complex(_ a: Int64) -> Int64 {
|
|
if a > 24 {
|
|
return a*a
|
|
}
|
|
return a/2
|
|
// CHECK_COMPLEX_RET: ret i{{.*}}, !dbg ![[COMPLEX_RET:.*]]
|
|
// CHECK_COMPLEX_RET: ![[COMPLEX_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_COMPLEX_SIMPLE < %t.ll
|
|
// CHECK_COMPLEX_SIMPLE: define {{.*}}complex_simple
|
|
public func complex_simple(_ a: Int64) -> Int64 {
|
|
if a > 24 {
|
|
return a*a
|
|
}
|
|
return 2
|
|
// CHECK_COMPLEX_SIMPLE: ret i{{.*}}, !dbg ![[COMPLEX_SIMPLE_RET:.*]]
|
|
// CHECK_COMPLEX_SIMPLE: ![[COMPLEX_SIMPLE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_SIMPLE_COMPLEX < %t.ll
|
|
// CHECK_SIMPLE_COMPLEX: define {{.*}}simple_complex
|
|
public func simple_complex(_ a: Int64) -> Int64 {
|
|
if a > 24 {
|
|
return a*a
|
|
}
|
|
return 2
|
|
// CHECK_SIMPLE_COMPLEX: ret {{.*}}, !dbg ![[SIMPLE_COMPLEX_RET:.*]]
|
|
// CHECK_SIMPLE_COMPLEX: ![[SIMPLE_COMPLEX_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_NONE < %t.ll
|
|
// CHECK_CLEANUP_NONE: define {{.*}}cleanup_none
|
|
public func cleanup_none(_ a: inout NSString) {
|
|
a = "empty"
|
|
// CHECK_CLEANUP_NONE: ret void, !dbg ![[CLEANUP_NONE_RET:.*]]
|
|
// CHECK_CLEANUP_NONE: ![[CLEANUP_NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_EMPTY < %t.ll
|
|
// CHECK_CLEANUP_EMPTY: define {{.*}}cleanup_empty
|
|
public func cleanup_empty(_ a: inout NSString) {
|
|
if a.length > 24 {
|
|
return
|
|
}
|
|
|
|
a = "empty"
|
|
return
|
|
// CHECK_CLEANUP_EMPTY: ret void, !dbg ![[CLEANUP_EMPTY_RET:.*]]
|
|
// CHECK_CLEANUP_EMPTY: ![[CLEANUP_EMPTY_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_EMPTY_NONE < %t.ll
|
|
// CHECK_CLEANUP_EMPTY_NONE: define {{.*}}cleanup_empty_none
|
|
public func cleanup_empty_none(_ a: inout NSString) {
|
|
if a.length > 24 {
|
|
return
|
|
}
|
|
|
|
a = "empty"
|
|
// CHECK_CLEANUP_EMPTY_NONE: ret {{.*}}, !dbg ![[CLEANUP_EMPTY_NONE_RET:.*]]
|
|
// CHECK_CLEANUP_EMPTY_NONE: ![[CLEANUP_EMPTY_NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_SIMPLE_RET < %t.ll
|
|
// CHECK_CLEANUP_SIMPLE_RET: define {{.*}}cleanup_simple
|
|
public func cleanup_simple(_ a: NSString) -> Int64 {
|
|
if a.length > 24 {
|
|
return 0
|
|
}
|
|
|
|
return 1
|
|
// CHECK_CLEANUP_SIMPLE_RET: ret {{.*}}, !dbg ![[CLEANUP_SIMPLE_RET:.*]]
|
|
// CHECK_CLEANUP_SIMPLE_RET: ![[CLEANUP_SIMPLE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_COMPLEX < %t.ll
|
|
// CHECK_CLEANUP_COMPLEX: define {{.*}}cleanup_complex
|
|
public func cleanup_complex(_ a: NSString) -> Int64 {
|
|
if a.length > 24 {
|
|
return Int64(a.length*a.length)
|
|
}
|
|
|
|
return Int64(a.length/2)
|
|
// CHECK_CLEANUP_COMPLEX: ret i{{.*}}, !dbg ![[CLEANUP_COMPLEX_RET:.*]]
|
|
// CHECK_CLEANUP_COMPLEX: ![[CLEANUP_COMPLEX_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_COMPLEX_SIMPLE < %t.ll
|
|
// CHECK_CLEANUP_COMPLEX_SIMPLE: define {{.*}}cleanup_complex_simple
|
|
public func cleanup_complex_simple(_ a: NSString) -> Int64 {
|
|
if a.length > 24 {
|
|
return Int64(a.length*a.length)
|
|
}
|
|
|
|
return 2
|
|
// CHECK_CLEANUP_COMPLEX_SIMPLE: ret i{{.*}}, !dbg ![[CLEANUP_COMPLEX_SIMPLE_RET:.*]]
|
|
// CHECK_CLEANUP_COMPLEX_SIMPLE: ![[CLEANUP_COMPLEX_SIMPLE_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_CLEANUP_SIMPLE_COMPLEX < %t.ll
|
|
// CHECK_CLEANUP_SIMPLE_COMPLEX: define {{.*}}cleanup_simple_complex
|
|
public func cleanup_simple_complex(_ a: NSString) -> Int64 {
|
|
if a.length > 24 {
|
|
return Int64(a.length*a.length)
|
|
}
|
|
return 2
|
|
// CHECK_CLEANUP_SIMPLE_COMPLEX: ret i{{.*}}, !dbg ![[CLEANUP_SIMPLE_COMPLEX_RET:.*]]
|
|
// CHECK_CLEANUP_SIMPLE_COMPLEX: ![[CLEANUP_SIMPLE_COMPLEX_RET]] = !DILocation(line: [[@LINE+1]], column: 1,
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// RUN: %FileCheck %s --check-prefix=CHECK_INIT < %t.ll
|
|
// CHECK_INIT: define {{.*}}$s4main6Class1CACSgycfc
|
|
public class Class1 {
|
|
public required init?() {
|
|
print("hello")
|
|
// CHECK_INIT: call {{.*}}@"$ss5print_9separator10terminatoryypd_S2StF"{{.*}}, !dbg ![[PRINTLOC:[0-9]+]]
|
|
// FIXME: Why doesn't ret have the correct line number?
|
|
// CHECK_INIT: ret i{{32|64}} 0, !dbg ![[PRINTLOC]]
|
|
// CHECK_INIT-DAG: [[PRINTLOC]] = !DILocation(line: [[@LINE-4]]
|
|
return nil
|
|
}
|
|
}
|