@@ -63,28 +63,31 @@ struct CheckString {
63
63
var dagNotStrings : Array < Pattern >
64
64
65
65
/// Match check string and its "not strings" and/or "dag strings".
66
- func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : BoxedTable , _ options: FileCheckOptions ) -> NSRange ? {
66
+ func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : [ String : String ] , _ options: FileCheckOptions ) -> ( NSRange , [ String : String ] ) ? {
67
67
// This condition is true when we are scanning forward to find CHECK-LABEL
68
68
// bounds we have not processed variable definitions within the bounded block
69
69
// yet so cannot handle any final CHECK-DAG yet this is handled when going
70
70
// over the block again (including the last CHECK-LABEL) in normal mode.
71
71
let lastPos : Int
72
72
let notStrings : [ Pattern ]
73
+ let initialTable : [ String : String ]
73
74
if !isLabelScanMode {
74
75
// Match "dag strings" (with mixed "not strings" if any).
75
- guard let ( lp, ns) = self . checkDAG ( buffer, variableTable, options) else {
76
+ guard let ( lp, ns, vt ) = self . checkDAG ( buffer, variableTable, options) else {
76
77
return nil
77
78
}
78
79
lastPos = lp
79
80
notStrings = ns
81
+ initialTable = vt
80
82
} else {
81
83
lastPos = 0
82
84
notStrings = [ ]
85
+ initialTable = variableTable
83
86
}
84
87
85
88
// Match itself from the last position after matching CHECK-DAG.
86
89
let matchBuffer = buffer. substring ( from: buffer. index ( buffer. startIndex, offsetBy: lastPos) )
87
- guard let range = self . pattern. match ( matchBuffer, variableTable ) else {
90
+ guard let ( range, mutVariableTable ) = self . pattern. match ( matchBuffer, initialTable ) else {
88
91
if let rtm = self . pattern. computeRegexToMatch ( variableTable) {
89
92
if !self . pattern. fixedString. isEmpty {
90
93
diagnose ( . error,
@@ -112,12 +115,14 @@ struct CheckString {
112
115
113
116
// Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
114
117
// or CHECK-NOT
118
+ let finalTable : [ String : String ]
115
119
if !isLabelScanMode {
120
+ let startIdx = buffer. index ( buffer. startIndex, offsetBy: lastPos)
116
121
let skippedRegion = buffer. substring (
117
122
with: Range < String . Index > (
118
123
uncheckedBounds: (
119
- buffer . index ( buffer . startIndex , offsetBy : lastPos ) ,
120
- buffer. index ( buffer . startIndex , offsetBy: matchPos)
124
+ startIdx ,
125
+ buffer. index ( startIdx , offsetBy: matchPos)
121
126
)
122
127
)
123
128
)
@@ -137,12 +142,16 @@ struct CheckString {
137
142
138
143
// If this match had "not strings", verify that they don't exist in the
139
144
// skipped region.
140
- if self . checkNot ( skippedRegion, notStrings, variableTable, options) {
145
+ let ( cond, variableTable) = self . checkNot ( skippedRegion, notStrings, mutVariableTable, options)
146
+ finalTable = variableTable
147
+ if cond {
141
148
return nil
142
149
}
150
+ } else {
151
+ finalTable = mutVariableTable
143
152
}
144
153
145
- return NSRange ( location: lastPos + matchPos, length: matchLen)
154
+ return ( NSRange ( location: lastPos + matchPos, length: matchLen) , finalTable )
146
155
}
147
156
148
157
/// Verify there is no newline in the given buffer.
@@ -226,34 +235,35 @@ struct CheckString {
226
235
}
227
236
228
237
/// Verify there's no "not strings" in the given buffer.
229
- private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ variableTable : BoxedTable , _ options: FileCheckOptions ) -> Bool {
238
+ private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ variableTable : [ String : String ] , _ options: FileCheckOptions ) -> ( Bool , [ String : String ] ) {
230
239
for pat in notStrings {
231
240
assert ( pat. type == . not, " Expect CHECK-NOT! " )
232
241
233
- guard let range = pat. match ( buffer, variableTable) else {
242
+ guard let ( range, variableTable ) = pat. match ( buffer, variableTable) else {
234
243
continue
235
244
}
236
245
buffer. cString ( using: . utf8) ? . withUnsafeBufferPointer { buf in
237
246
let loc = CheckLoc . inBuffer ( buf. baseAddress!. advanced ( by: range. location) , buf)
238
247
diagnose ( . error, at: loc, with: self . prefix + " -NOT: string occurred! " , options: options)
239
248
}
240
249
diagnose ( . note, at: pat. patternLoc, with: self . prefix + " -NOT: pattern specified here " , options: options)
241
- return true
250
+ return ( true , variableTable )
242
251
}
243
252
244
- return false
253
+ return ( false , variableTable )
245
254
}
246
255
247
256
/// Match "dag strings" and their mixed "not strings".
248
- func checkDAG( _ buffer : String , _ variableTable : BoxedTable , _ options: FileCheckOptions ) -> ( Int , [ Pattern ] ) ? {
257
+ func checkDAG( _ buffer : String , _ variableTable : [ String : String ] , _ options: FileCheckOptions ) -> ( Int , [ Pattern ] , [ String : String ] ) ? {
249
258
var notStrings = [ Pattern] ( )
250
- if dagNotStrings. isEmpty {
251
- return ( 0 , notStrings)
259
+ if self . dagNotStrings. isEmpty {
260
+ return ( 0 , notStrings, variableTable )
252
261
}
253
262
254
263
var lastPos = 0
255
264
var startPos = lastPos
256
265
266
+ var finalTable : [ String : String ] = variableTable
257
267
for pattern in self . dagNotStrings {
258
268
assert ( ( pattern. type == . dag || pattern. type == . not) , " Invalid CHECK-DAG or CHECK-NOT! " )
259
269
@@ -268,10 +278,11 @@ struct CheckString {
268
278
let matchBuffer = buffer. substring ( from: buffer. index ( buffer. startIndex, offsetBy: startPos) )
269
279
// With a group of CHECK-DAGs, a single mismatching means the match on
270
280
// that group of CHECK-DAGs fails immediately.
271
- guard let range = pattern. match ( matchBuffer, variableTable ) else {
281
+ guard let ( range, variableTable ) = pattern. match ( matchBuffer, finalTable ) else {
272
282
// PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable)
273
283
return nil
274
284
}
285
+ finalTable = variableTable
275
286
276
287
// Re-calc it as the offset relative to the start of the original string.
277
288
let matchPos = range. location + startPos
@@ -302,9 +313,11 @@ struct CheckString {
302
313
)
303
314
)
304
315
)
305
- if self . checkNot ( skippedRegion, notStrings, variableTable, options) {
316
+ let ( cond, mutVarTable) = self . checkNot ( skippedRegion, notStrings, finalTable, options)
317
+ if cond {
306
318
return nil
307
319
}
320
+ finalTable = mutVarTable
308
321
// Clear "not strings".
309
322
notStrings. removeAll ( )
310
323
}
@@ -313,6 +326,6 @@ struct CheckString {
313
326
lastPos = max ( matchPos + range. length, lastPos)
314
327
}
315
328
316
- return ( lastPos, notStrings)
329
+ return ( lastPos, notStrings, finalTable )
317
330
}
318
331
}
0 commit comments