@@ -50,16 +50,9 @@ extension ProjectedValue {
50
50
/// The provided `visitor` can be used to override the handling a certain defs and uses during
51
51
/// the walk. See `EscapeVisitor` for details.
52
52
///
53
- /// By default, the walk starts in upward direction. This makes sense most of the time. But for
54
- /// some use cases, e.g. to check if an argument escapes inside the function (without
55
- /// considering potential escapes in the caller), the walk must start downwards - by setting
56
- /// `startWalkingDown` to true.
57
- ///
58
- func isEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) ,
59
- startWalkingDown: Bool = false ,
60
- _ context: PassContext ) -> Bool {
53
+ func isEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) , _ context: PassContext ) -> Bool {
61
54
var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: false , context)
62
- return walker. isEscaping ( self , startWalkingDown : startWalkingDown )
55
+ return walker. walkUp ( addressOrValue : value , path : escapePath ( path ) ) == . abortWalk
63
56
}
64
57
65
58
/// Returns true if the projected address value escapes.
@@ -70,11 +63,21 @@ extension ProjectedValue {
70
63
/// not the value stored at the address.
71
64
/// * Addresses with trivial types are _not_ ignored.
72
65
///
73
- func isAddressEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) ,
74
- startWalkingDown: Bool = false ,
75
- _ context: PassContext ) -> Bool {
66
+ func isAddressEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) , _ context: PassContext ) -> Bool {
76
67
var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: true , context)
77
- return walker. isEscaping ( self , startWalkingDown: startWalkingDown)
68
+ return walker. walkUp ( addressOrValue: value, path: escapePath ( path) ) == . abortWalk
69
+ }
70
+
71
+ /// Returns true if the function argument escapes, but ignoring any potential escapes in the caller.
72
+ ///
73
+ /// This function is similar to `ProjectedValue.isEscaping()`, but it ignores any potential
74
+ /// escapes which might have happened before the argument's function is called.
75
+ /// Technically, this means that the walk starts downwards instead of upwards.
76
+ ///
77
+ func isEscapingWhenWalkingDown< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) ,
78
+ _ context: PassContext ) -> Bool {
79
+ var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: false , context)
80
+ return walker. walkDown ( addressOrValue: value, path: escapePath ( path) ) == . abortWalk
78
81
}
79
82
80
83
/// Returns the result of the visitor if the projected value does not escape.
@@ -83,11 +86,9 @@ extension ProjectedValue {
83
86
/// it returns the `result` of the `visitor`, if the projected value does not escape.
84
87
/// Returns nil, if the projected value escapes.
85
88
///
86
- func visit< V: EscapeVisitorWithResult > ( using visitor: V ,
87
- startWalkingDown: Bool = false ,
88
- _ context: PassContext ) -> V . Result ? {
89
+ func visit< V: EscapeVisitorWithResult > ( using visitor: V , _ context: PassContext ) -> V . Result ? {
89
90
var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: false , context)
90
- if walker. isEscaping ( self , startWalkingDown : startWalkingDown ) {
91
+ if walker. walkUp ( addressOrValue : value , path : escapePath ( path ) ) == . abortWalk {
91
92
return nil
92
93
}
93
94
return walker. visitor. result
@@ -99,16 +100,29 @@ extension ProjectedValue {
99
100
/// it returns the `result` of the `visitor`, if the projected address does not escape.
100
101
/// Returns nil, if the projected address escapes.
101
102
///
102
- func visitAddress< V: EscapeVisitorWithResult > ( using visitor: V ,
103
- startWalkingDown: Bool = false ,
104
- _ context: PassContext ) -> V . Result ? {
103
+ func visitAddress< V: EscapeVisitorWithResult > ( using visitor: V , _ context: PassContext ) -> V . Result ? {
105
104
var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: true , context)
106
- if walker. isEscaping ( self , startWalkingDown : startWalkingDown ) {
105
+ if walker. walkUp ( addressOrValue : value , path : escapePath ( path ) ) == . abortWalk {
107
106
return nil
108
107
}
109
108
return walker. visitor. result
110
109
}
111
110
111
+ /// Returns the result of the visitor if the projected value does not escape - ignoring
112
+ /// any potential escapes in the caller.
113
+ ///
114
+ /// This function is similar to `isEscapingIgnoringCallerEscapes() -> Bool`, but instead
115
+ /// of returning a Bool, it returns the `result` of the `visitor`.
116
+ ///
117
+ func visitByWalkingDown< V: EscapeVisitorWithResult > ( using visitor: V ,
118
+ _ context: PassContext ) -> V . Result ? {
119
+ var walker = EscapeWalker ( visitor: visitor, analyzeAddresses: false , context)
120
+ if walker. walkDown ( addressOrValue: value, path: escapePath ( path) ) == . abortWalk {
121
+ return nil
122
+ }
123
+ return walker. visitor. result
124
+ }
125
+
112
126
/// Returns true if the address can alias with `rhs`.
113
127
///
114
128
/// Example:
@@ -132,19 +146,16 @@ extension ProjectedValue {
132
146
}
133
147
return true
134
148
}
135
-
136
149
}
137
150
138
151
extension Value {
139
152
/// The un-projected version of `ProjectedValue.isEscaping()`.
140
- func isEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) ,
141
- _ context: PassContext ) -> Bool {
153
+ func isEscaping< V: EscapeVisitor > ( using visitor: V = DefaultVisitor ( ) , _ context: PassContext ) -> Bool {
142
154
return self . at ( SmallProjectionPath ( ) ) . isEscaping ( using: visitor, context)
143
155
}
144
156
145
157
/// The un-projected version of `ProjectedValue.visit()`.
146
- func visit< V: EscapeVisitorWithResult > ( using visitor: V ,
147
- _ context: PassContext ) -> V . Result ? {
158
+ func visit< V: EscapeVisitorWithResult > ( using visitor: V , _ context: PassContext ) -> V . Result ? {
148
159
return self . at ( SmallProjectionPath ( ) ) . visit ( using: visitor, context)
149
160
}
150
161
}
@@ -328,14 +339,6 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
328
339
self . analyzeAddresses = analyzeAddresses
329
340
}
330
341
331
- mutating func isEscaping( _ projValue: ProjectedValue , startWalkingDown: Bool ) -> Bool {
332
- if startWalkingDown {
333
- return walkDown ( addressOrValue: projValue. value, path: escapePath ( projValue. path) ) == . abortWalk
334
- } else {
335
- return walkUp ( addressOrValue: projValue. value, path: escapePath ( projValue. path) ) == . abortWalk
336
- }
337
- }
338
-
339
342
//===--------------------------------------------------------------------===//
340
343
// Walking down
341
344
//===--------------------------------------------------------------------===//
0 commit comments