@@ -63,28 +63,31 @@ struct CheckString {
6363 var dagNotStrings : Array < Pattern >
6464
6565 /// 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 ] ) ? {
6767 // This condition is true when we are scanning forward to find CHECK-LABEL
6868 // bounds we have not processed variable definitions within the bounded block
6969 // yet so cannot handle any final CHECK-DAG yet this is handled when going
7070 // over the block again (including the last CHECK-LABEL) in normal mode.
7171 let lastPos : Int
7272 let notStrings : [ Pattern ]
73+ let initialTable : [ String : String ]
7374 if !isLabelScanMode {
7475 // 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 {
7677 return nil
7778 }
7879 lastPos = lp
7980 notStrings = ns
81+ initialTable = vt
8082 } else {
8183 lastPos = 0
8284 notStrings = [ ]
85+ initialTable = variableTable
8386 }
8487
8588 // Match itself from the last position after matching CHECK-DAG.
8689 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 {
8891 if let rtm = self . pattern. computeRegexToMatch ( variableTable) {
8992 if !self . pattern. fixedString. isEmpty {
9093 diagnose ( . error,
@@ -112,12 +115,14 @@ struct CheckString {
112115
113116 // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
114117 // or CHECK-NOT
118+ let finalTable : [ String : String ]
115119 if !isLabelScanMode {
120+ let startIdx = buffer. index ( buffer. startIndex, offsetBy: lastPos)
116121 let skippedRegion = buffer. substring (
117122 with: Range < String . Index > (
118123 uncheckedBounds: (
119- buffer . index ( buffer . startIndex , offsetBy : lastPos ) ,
120- buffer. index ( buffer . startIndex , offsetBy: matchPos)
124+ startIdx ,
125+ buffer. index ( startIdx , offsetBy: matchPos)
121126 )
122127 )
123128 )
@@ -137,12 +142,16 @@ struct CheckString {
137142
138143 // If this match had "not strings", verify that they don't exist in the
139144 // 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 {
141148 return nil
142149 }
150+ } else {
151+ finalTable = mutVariableTable
143152 }
144153
145- return NSRange ( location: lastPos + matchPos, length: matchLen)
154+ return ( NSRange ( location: lastPos + matchPos, length: matchLen) , finalTable )
146155 }
147156
148157 /// Verify there is no newline in the given buffer.
@@ -226,34 +235,35 @@ struct CheckString {
226235 }
227236
228237 /// 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 ] ) {
230239 for pat in notStrings {
231240 assert ( pat. type == . not, " Expect CHECK-NOT! " )
232241
233- guard let range = pat. match ( buffer, variableTable) else {
242+ guard let ( range, variableTable ) = pat. match ( buffer, variableTable) else {
234243 continue
235244 }
236245 buffer. cString ( using: . utf8) ? . withUnsafeBufferPointer { buf in
237246 let loc = CheckLoc . inBuffer ( buf. baseAddress!. advanced ( by: range. location) , buf)
238247 diagnose ( . error, at: loc, with: self . prefix + " -NOT: string occurred! " , options: options)
239248 }
240249 diagnose ( . note, at: pat. patternLoc, with: self . prefix + " -NOT: pattern specified here " , options: options)
241- return true
250+ return ( true , variableTable )
242251 }
243252
244- return false
253+ return ( false , variableTable )
245254 }
246255
247256 /// 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 ] ) ? {
249258 var notStrings = [ Pattern] ( )
250- if dagNotStrings. isEmpty {
251- return ( 0 , notStrings)
259+ if self . dagNotStrings. isEmpty {
260+ return ( 0 , notStrings, variableTable )
252261 }
253262
254263 var lastPos = 0
255264 var startPos = lastPos
256265
266+ var finalTable : [ String : String ] = variableTable
257267 for pattern in self . dagNotStrings {
258268 assert ( ( pattern. type == . dag || pattern. type == . not) , " Invalid CHECK-DAG or CHECK-NOT! " )
259269
@@ -268,10 +278,11 @@ struct CheckString {
268278 let matchBuffer = buffer. substring ( from: buffer. index ( buffer. startIndex, offsetBy: startPos) )
269279 // With a group of CHECK-DAGs, a single mismatching means the match on
270280 // 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 {
272282 // PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable)
273283 return nil
274284 }
285+ finalTable = variableTable
275286
276287 // Re-calc it as the offset relative to the start of the original string.
277288 let matchPos = range. location + startPos
@@ -302,9 +313,11 @@ struct CheckString {
302313 )
303314 )
304315 )
305- if self . checkNot ( skippedRegion, notStrings, variableTable, options) {
316+ let ( cond, mutVarTable) = self . checkNot ( skippedRegion, notStrings, finalTable, options)
317+ if cond {
306318 return nil
307319 }
320+ finalTable = mutVarTable
308321 // Clear "not strings".
309322 notStrings. removeAll ( )
310323 }
@@ -313,6 +326,6 @@ struct CheckString {
313326 lastPos = max ( matchPos + range. length, lastPos)
314327 }
315328
316- return ( lastPos, notStrings)
329+ return ( lastPos, notStrings, finalTable )
317330 }
318331}
0 commit comments