2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
28 module Ast
= Ast_cocci
29 module V
= Visitor_ast
31 let disjmult2 e1 e2 k
=
33 (List.map
(function e1
-> List.map
(function e2
-> k e1 e2
) e2
) e1
)
35 let disjmult3 e1 e2 e3 k
=
41 (function e2
-> List.map
(function e3
-> k e1 e2 e3
) e3
)
45 let rec disjmult f
= function
49 let rest = disjmult f xs
in
50 disjmult2 cur rest (function cur -> function rest -> cur :: rest)
52 let rec disjmult_two fstart frest
(start
,rest) =
53 let cur = fstart start
in
54 let rest = disjmult frest
rest in
55 disjmult2 cur rest (function cur -> function rest -> (cur,rest))
57 let disjoption f
= function
59 | Some x
-> List.map
(function x
-> Some x
) (f x
)
62 match Ast.unwrap d
with
64 List.map
(function l
-> Ast.rewrap d
(Ast.DOTS
(l
))) (disjmult f l
)
66 List.map
(function l
-> Ast.rewrap d
(Ast.CIRCLES
(l
))) (disjmult f l
)
68 List.map
(function l
-> Ast.rewrap d
(Ast.STARS
(l
))) (disjmult f l
)
71 match Ast.unwrap ft
with
72 Ast.Type
(allminus
,cv
,ty
) ->
73 let ty = disjtypeC
ty in
74 List.map
(function ty -> Ast.rewrap ft
(Ast.Type
(allminus
,cv
,ty))) ty
75 | Ast.AsType
(ty,asty
) -> (* as ty doesn't contain disj *)
77 List.map
(function ty -> Ast.rewrap ft
(Ast.AsType
(ty,asty
))) ty
78 | Ast.DisjType
(types
) -> List.concat
(List.map
disjty types
)
81 List.map
(function ty -> Ast.rewrap ft
(Ast.OptType
(ty))) ty
82 | Ast.UniqueType
(ty) ->
84 List.map
(function ty -> Ast.rewrap ft
(Ast.UniqueType
(ty))) ty
87 match Ast.unwrap bty
with
88 Ast.BaseType
(_
) | Ast.SignedT
(_
,_
) -> [bty
]
89 | Ast.Pointer
(ty,star
) ->
91 List.map
(function ty -> Ast.rewrap bty
(Ast.Pointer
(ty,star
))) ty
92 | Ast.FunctionPointer
(ty,lp1
,star
,rp1
,lp2
,params
,rp2
) ->
96 Ast.rewrap bty
(Ast.FunctionPointer
(ty,lp1
,star
,rp1
,lp2
,params
,rp2
)))
98 | Ast.FunctionType
(s
,ty,lp1
,params
,rp1
) ->
99 let ty = disjoption disjty ty in
102 Ast.rewrap bty
(Ast.FunctionType
(s
,ty,lp1
,params
,rp1
)))
104 | Ast.Array
(ty,lb
,size
,rb
) ->
105 disjmult2 (disjty ty) (disjoption disjexp size
)
106 (function ty -> function size
->
107 Ast.rewrap bty
(Ast.Array
(ty,lb
,size
,rb
)))
108 | Ast.EnumName
(_
,_
) | Ast.StructUnionName
(_
,_
) -> [bty
]
109 | Ast.EnumDef
(ty,lb
,ids
,rb
) ->
110 disjmult2 (disjty ty) (disjdots disjexp ids
)
111 (function ty -> function ids
->
112 Ast.rewrap bty
(Ast.EnumDef
(ty,lb
,ids
,rb
)))
113 | Ast.StructUnionDef
(ty,lb
,decls
,rb
) ->
114 disjmult2 (disjty ty) (disjdots disjdecl decls
)
115 (function ty -> function decls
->
116 Ast.rewrap bty
(Ast.StructUnionDef
(ty,lb
,decls
,rb
)))
117 | Ast.TypeName
(_
) | Ast.MetaType
(_
,_
,_
) -> [bty
]
120 match Ast.unwrap e
with
121 Ast.DisjId
(id_list
) -> List.concat
(List.map disjident id_list
)
122 | Ast.OptIdent
(id
) ->
123 let id = disjident
id in
124 List.map
(function id -> Ast.rewrap e
(Ast.OptIdent
(id))) id
125 | Ast.UniqueIdent
(id) ->
126 let id = disjident
id in
127 List.map
(function id -> Ast.rewrap e
(Ast.UniqueIdent
(id))) id
131 match Ast.unwrap e
with
132 Ast.Ident
(_
) | Ast.Constant
(_
) -> [e
] (* even Ident can't contain disj *)
133 | Ast.FunCall
(fn
,lp
,args
,rp
) ->
134 disjmult2 (disjexp fn
) (disjdots disjexp args
)
135 (function fn
-> function args
->
136 Ast.rewrap e
(Ast.FunCall
(fn
,lp
,args
,rp
)))
137 | Ast.Assignment
(left
,op
,right
,simple
) ->
138 disjmult2 (disjexp left
) (disjexp right
)
139 (function left
-> function right
->
140 Ast.rewrap e
(Ast.Assignment
(left
,op
,right
,simple
)))
141 | Ast.Sequence
(left
,op
,right
) ->
142 disjmult2 (disjexp left
) (disjexp right
)
143 (function left
-> function right
->
144 Ast.rewrap e
(Ast.Sequence
(left
,op
,right
)))
145 | Ast.CondExpr
(exp1
,why
,Some exp2
,colon
,exp3
) ->
146 let res = disjmult disjexp
[exp1
;exp2
;exp3
] in
150 Ast.rewrap e
(Ast.CondExpr
(exp1
,why
,Some exp2
,colon
,exp3
))
151 | _
-> failwith
"not possible")
153 | Ast.CondExpr
(exp1
,why
,None
,colon
,exp3
) ->
154 disjmult2 (disjexp exp1
) (disjexp exp3
)
155 (function exp1
-> function exp3
->
156 Ast.rewrap e
(Ast.CondExpr
(exp1
,why
,None
,colon
,exp3
)))
157 | Ast.Postfix
(exp
,op
) ->
158 let exp = disjexp
exp in
159 List.map
(function exp -> Ast.rewrap e
(Ast.Postfix
(exp,op
))) exp
160 | Ast.Infix
(exp,op
) ->
161 let exp = disjexp
exp in
162 List.map
(function exp -> Ast.rewrap e
(Ast.Infix
(exp,op
))) exp
163 | Ast.Unary
(exp,op
) ->
164 let exp = disjexp
exp in
165 List.map
(function exp -> Ast.rewrap e
(Ast.Unary
(exp,op
))) exp
166 | Ast.Binary
(left
,op
,right
) ->
167 disjmult2 (disjexp left
) (disjexp right
)
168 (function left
-> function right
->
169 Ast.rewrap e
(Ast.Binary
(left
,op
,right
)))
170 | Ast.Nested
(exp,op
,right
) ->
171 (* disj not possible in right *)
172 let exp = disjexp
exp in
173 List.map
(function exp -> Ast.rewrap e
(Ast.Nested
(exp,op
,right
))) exp
174 | Ast.Paren
(lp
,exp,rp
) ->
175 let exp = disjexp
exp in
176 List.map
(function exp -> Ast.rewrap e
(Ast.Paren
(lp
,exp,rp
))) exp
177 | Ast.ArrayAccess
(exp1
,lb
,exp2
,rb
) ->
178 disjmult2 (disjexp exp1
) (disjexp exp2
)
179 (function exp1
-> function exp2
->
180 Ast.rewrap e
(Ast.ArrayAccess
(exp1
,lb
,exp2
,rb
)))
181 | Ast.RecordAccess
(exp,pt
,field
) ->
182 let exp = disjexp
exp in
184 (function exp -> Ast.rewrap e
(Ast.RecordAccess
(exp,pt
,field
))) exp
185 | Ast.RecordPtAccess
(exp,ar
,field
) ->
186 let exp = disjexp
exp in
188 (function exp -> Ast.rewrap e
(Ast.RecordPtAccess
(exp,ar
,field
))) exp
189 | Ast.Cast
(lp
,ty,rp
,exp) ->
190 disjmult2 (disjty ty) (disjexp
exp)
191 (function ty -> function exp -> Ast.rewrap e
(Ast.Cast
(lp
,ty,rp
,exp)))
192 | Ast.SizeOfExpr
(szf
,exp) ->
193 let exp = disjexp
exp in
194 List.map
(function exp -> Ast.rewrap e
(Ast.SizeOfExpr
(szf
,exp))) exp
195 | Ast.SizeOfType
(szf
,lp
,ty,rp
) ->
196 let ty = disjty ty in
198 (function ty -> Ast.rewrap e
(Ast.SizeOfType
(szf
,lp
,ty,rp
))) ty
200 let ty = disjty ty in
201 List.map
(function ty -> Ast.rewrap e
(Ast.TypeExp
(ty))) ty
202 | Ast.Constructor
(lp
,ty,rp
,init
) ->
203 disjmult2 (disjty ty) (disjini init
)
205 function exp -> Ast.rewrap e
(Ast.Constructor
(lp
,ty,rp
,init
)))
206 | Ast.MetaErr
(_
,_
,_
,_
) | Ast.MetaExpr
(_
,_
,_
,_
,_
,_
)
207 | Ast.MetaExprList
(_
,_
,_
,_
) | Ast.EComma
(_
) -> [e
]
208 | Ast.AsExpr
(exp,asexp
) -> (* as exp doesn't contain disj *)
209 let exp = disjexp
exp in
210 List.map
(function exp -> Ast.rewrap e
(Ast.AsExpr
(exp,asexp
))) exp
211 | Ast.DisjExpr
(exp_list
) -> List.concat
(List.map disjexp exp_list
)
212 | Ast.NestExpr
(starter
,expr_dots
,ender
,whencode
,multi
) ->
213 (* not sure what to do here, so ambiguities still possible *)
215 | Ast.Edots
(dots
,_
) | Ast.Ecircles
(dots
,_
) | Ast.Estars
(dots
,_
) -> [e
]
217 let exp = disjexp
exp in
218 List.map
(function exp -> Ast.rewrap e
(Ast.OptExp
(exp))) exp
219 | Ast.UniqueExp
(exp) ->
220 let exp = disjexp
exp in
221 List.map
(function exp -> Ast.rewrap e
(Ast.UniqueExp
(exp))) exp
224 match Ast.unwrap p
with
225 Ast.VoidParam
(ty) -> [p
] (* void is the only possible value *)
226 | Ast.Param
(ty,id) ->
227 let ty = disjty ty in
228 List.map
(function ty -> Ast.rewrap p
(Ast.Param
(ty,id))) ty
229 | Ast.AsParam
(pm
,asexp
) -> (* as exp doesn't contain disj *)
230 let pm = disjparam
pm in
231 List.map
(function pm -> Ast.rewrap p
(Ast.AsParam
(pm,asexp
))) pm
232 | Ast.MetaParam
(_
,_
,_
) | Ast.MetaParamList
(_
,_
,_
,_
) | Ast.PComma
(_
) -> [p
]
233 | Ast.Pdots
(dots
) | Ast.Pcircles
(dots
) -> [p
]
234 | Ast.OptParam
(param
) ->
235 let param = disjparam
param in
236 List.map
(function param -> Ast.rewrap p
(Ast.OptParam
(param))) param
237 | Ast.UniqueParam
(param) ->
238 let param = disjparam
param in
239 List.map
(function param -> Ast.rewrap p
(Ast.UniqueParam
(param))) param
242 match Ast.unwrap i
with
243 Ast.MetaInit
(_
,_
,_
) | Ast.MetaInitList
(_
,_
,_
,_
) -> [i
]
244 | Ast.AsInit
(ini
,asini
) ->
245 let ini = disjini
ini in
246 List.map
(function ini -> Ast.rewrap i
(Ast.AsInit
(ini,asini
))) ini
247 | Ast.InitExpr
(exp) ->
248 let exp = disjexp
exp in
249 List.map
(function exp -> Ast.rewrap i
(Ast.InitExpr
(exp))) exp
250 | Ast.ArInitList
(lb
,initlist
,rb
) ->
252 (function initlist
->
253 Ast.rewrap i
(Ast.ArInitList
(lb
,initlist
,rb
)))
254 (disjdots disjini initlist
)
255 | Ast.StrInitList
(allminus
,lb
,initlist
,rb
,whencode
) ->
257 (function initlist
->
258 Ast.rewrap i
(Ast.StrInitList
(allminus
,lb
,initlist
,rb
,whencode
)))
259 (disjmult disjini initlist
)
260 | Ast.InitGccExt
(designators
,eq
,ini) ->
261 let designators = disjmult designator
designators in
262 let ini = disjini
ini in
263 disjmult2 designators ini
264 (function designators -> function ini ->
265 Ast.rewrap i
(Ast.InitGccExt
(designators,eq
,ini)))
266 | Ast.InitGccName
(name
,eq
,ini) ->
267 let ini = disjini
ini in
269 (function ini -> Ast.rewrap i
(Ast.InitGccName
(name
,eq
,ini)))
271 | Ast.IComma
(comma
) -> [i
]
272 | Ast.Idots
(dots
,_
) -> [i
]
274 let ini = disjini
ini in
275 List.map
(function ini -> Ast.rewrap i
(Ast.OptIni
(ini))) ini
276 | Ast.UniqueIni
(ini) ->
277 let ini = disjini
ini in
278 List.map
(function ini -> Ast.rewrap i
(Ast.UniqueIni
(ini))) ini
280 and designator
= function
281 Ast.DesignatorField
(dot
,id) -> [Ast.DesignatorField
(dot
,id)]
282 | Ast.DesignatorIndex
(lb
,exp,rb
) ->
283 let exp = disjexp
exp in
284 List.map
(function exp -> Ast.DesignatorIndex
(lb
,exp,rb
)) exp
285 | Ast.DesignatorRange
(lb
,min
,dots
,max
,rb
) ->
286 disjmult2 (disjexp min
) (disjexp max
)
287 (function min
-> function max
->
288 Ast.DesignatorRange
(lb
,min
,dots
,max
,rb
))
291 match Ast.unwrap d
with
292 Ast.MetaDecl
(_
,_
,_
) | Ast.MetaField
(_
,_
,_
)
293 | Ast.MetaFieldList
(_
,_
,_
,_
) -> [d
]
294 | Ast.AsDecl
(decl
,asdecl
) ->
295 let decl = disjdecl
decl in
296 List.map
(function decl -> Ast.rewrap d
(Ast.AsDecl
(decl,asdecl
))) decl
297 | Ast.Init
(stg
,ty,id,eq
,ini,sem
) ->
298 disjmult2 (disjty ty) (disjini
ini)
299 (function ty -> function ini ->
300 Ast.rewrap d
(Ast.Init
(stg
,ty,id,eq
,ini,sem
)))
301 | Ast.UnInit
(stg
,ty,id,sem
) ->
302 let ty = disjty ty in
303 List.map
(function ty -> Ast.rewrap d
(Ast.UnInit
(stg
,ty,id,sem
))) ty
304 | Ast.MacroDecl
(name
,lp
,args
,rp
,sem
) ->
306 (function args
-> Ast.rewrap d
(Ast.MacroDecl
(name
,lp
,args
,rp
,sem
)))
307 (disjdots disjexp args
)
308 | Ast.MacroDeclInit
(name
,lp
,args
,rp
,eq
,ini,sem
) ->
309 disjmult2 (disjdots disjexp args
) (disjini
ini)
310 (function args
-> function ini ->
311 Ast.rewrap d
(Ast.MacroDeclInit
(name
,lp
,args
,rp
,eq
,ini,sem
)))
312 | Ast.TyDecl
(ty,sem
) ->
313 let ty = disjty ty in
314 List.map
(function ty -> Ast.rewrap d
(Ast.TyDecl
(ty,sem
))) ty
315 | Ast.Typedef
(stg
,ty,id,sem
) ->
316 let ty = disjty ty in (* disj not allowed in id *)
317 List.map
(function ty -> Ast.rewrap d
(Ast.Typedef
(stg
,ty,id,sem
))) ty
318 | Ast.DisjDecl
(decls
) -> List.concat
(List.map disjdecl decls
)
319 | Ast.Ddots
(_
,_
) -> [d
]
320 | Ast.OptDecl
(decl) ->
321 let decl = disjdecl
decl in
322 List.map
(function decl -> Ast.rewrap d
(Ast.OptDecl
(decl))) decl
323 | Ast.UniqueDecl
(decl) ->
324 let decl = disjdecl
decl in
325 List.map
(function decl -> Ast.rewrap d
(Ast.UniqueDecl
(decl))) decl
327 let generic_orify_rule_elem f re
exp rebuild
=
330 | orexps
-> Ast.rewrap re
(Ast.DisjRuleElem
(List.map rebuild orexps
))
332 let orify_rule_elem re
exp rebuild
=
333 generic_orify_rule_elem disjexp re
exp rebuild
335 let orify_rule_elem_ty = generic_orify_rule_elem disjty
336 let orify_rule_elem_param = generic_orify_rule_elem disjparam
337 let orify_rule_elem_decl = generic_orify_rule_elem disjdecl
338 let orify_rule_elem_ini = generic_orify_rule_elem disjini
340 let rec disj_rule_elem r k re
=
341 match Ast.unwrap re
with
342 Ast.FunHeader
(bef
,allminus
,fninfo
,name
,lp
,params
,rp
) ->
343 generic_orify_rule_elem (disjdots disjparam
) re params
346 (Ast.FunHeader
(bef
,allminus
,fninfo
,name
,lp
,params
,rp
)))
347 | Ast.Decl
(bef
,allminus
,decl) ->
348 orify_rule_elem_decl re
decl
349 (function decl -> Ast.rewrap re
(Ast.Decl
(bef
,allminus
,decl)))
350 | Ast.SeqStart
(brace
) -> re
351 | Ast.SeqEnd
(brace
) -> re
352 | Ast.ExprStatement
(Some
exp,sem
) ->
353 orify_rule_elem re
exp
354 (function exp -> Ast.rewrap re
(Ast.ExprStatement
(Some
exp,sem
)))
355 | Ast.ExprStatement
(None
,sem
) -> re
356 | Ast.IfHeader
(iff
,lp
,exp,rp
) ->
357 orify_rule_elem re
exp
358 (function exp -> Ast.rewrap re
(Ast.IfHeader
(iff
,lp
,exp,rp
)))
359 | Ast.Else
(els
) -> re
360 | Ast.WhileHeader
(whl
,lp
,exp,rp
) ->
361 orify_rule_elem re
exp
362 (function exp -> Ast.rewrap re
(Ast.WhileHeader
(whl
,lp
,exp,rp
)))
363 | Ast.DoHeader
(d
) -> re
364 | Ast.WhileTail
(whl
,lp
,exp,rp
,sem
) ->
365 orify_rule_elem re
exp
366 (function exp -> Ast.rewrap re
(Ast.WhileTail
(whl
,lp
,exp,rp
,sem
)))
367 | Ast.ForHeader
(fr
,lp
,first
,e2
,sem2
,e3
,rp
) ->
368 let disjfirst = function
369 Ast.ForExp
(e1
,sem1
) ->
370 List.map
(function e1
-> Ast.ForExp
(e1
,sem1
))
371 (disjoption disjexp e1
)
372 | Ast.ForDecl
(bef
,allminus
,decl) ->
373 List.map
(function decl -> Ast.ForDecl
(bef
,allminus
,decl))
375 generic_orify_rule_elem
376 (disjmult_two disjfirst (disjoption disjexp
)) re
(first
,[e2
;e3
])
378 (first
,[exp2
;exp3
]) ->
379 Ast.rewrap re
(Ast.ForHeader
(fr
,lp
,first
,exp2
,sem2
,exp3
,rp
))
380 | _
-> failwith
"not possible")
381 | Ast.IteratorHeader
(whl
,lp
,args
,rp
) ->
382 generic_orify_rule_elem (disjdots disjexp
) re args
383 (function args
-> Ast.rewrap re
(Ast.IteratorHeader
(whl
,lp
,args
,rp
)))
384 | Ast.SwitchHeader
(switch
,lp
,exp,rp
) ->
385 orify_rule_elem re
exp
386 (function exp -> Ast.rewrap re
(Ast.SwitchHeader
(switch
,lp
,exp,rp
)))
387 | Ast.Break
(_
,_
) | Ast.Continue
(_
,_
) | Ast.Label
(_
,_
) | Ast.Goto
(_
,_
,_
)
388 | Ast.Return
(_
,_
) -> re
389 | Ast.ReturnExpr
(ret
,exp,sem
) ->
390 orify_rule_elem re
exp
391 (function exp -> Ast.rewrap re
(Ast.ReturnExpr
(ret
,exp,sem
)))
392 | Ast.MetaRuleElem
(_
,_
,_
) | Ast.MetaStmt
(_
,_
,_
,_
)
393 | Ast.MetaStmtList
(_
,_
,_
) -> re
395 orify_rule_elem re
exp (function exp -> Ast.rewrap
exp (Ast.Exp
(exp)))
397 orify_rule_elem re
exp (function exp -> Ast.rewrap
exp (Ast.TopExp
(exp)))
399 orify_rule_elem_ty re
ty (function ty -> Ast.rewrap
ty (Ast.Ty
(ty)))
400 | Ast.TopInit
(init
) ->
401 orify_rule_elem_ini re init
402 (function init
-> Ast.rewrap init
(Ast.TopInit
(init
)))
403 | Ast.Include
(inc
,s
) -> re
404 | Ast.Undef
(def
,id) -> re
405 | Ast.DefineHeader
(def
,id,params
) -> re
406 | Ast.Default
(def
,colon
) -> re
407 | Ast.Case
(case
,exp,colon
) ->
408 orify_rule_elem re
exp
409 (function exp -> Ast.rewrap re
(Ast.Case
(case
,exp,colon
)))
410 | Ast.DisjRuleElem
(l
) ->
411 (* only case lines *)
412 Ast.rewrap re
(Ast.DisjRuleElem
(List.map
(disj_rule_elem r k
) l
))
416 let donothing r k e
= k e
in
418 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
419 donothing donothing donothing donothing donothing
420 donothing donothing donothing donothing donothing donothing donothing
421 disj_rule_elem donothing donothing donothing donothing
423 (* ----------------------------------------------------------------------- *)
424 (* collect iso information at the rule_elem level *)
426 let collect_all_isos =
428 let option_default = [] in
429 let mcode r x
= [] in
430 let donothing r k e
= Common.union_set
(Ast.get_isos e
) (k e
) in
431 let doanything r k e
= k e
in
432 V.combiner
bind option_default
433 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
434 donothing donothing donothing donothing donothing donothing donothing
435 donothing donothing donothing donothing donothing donothing donothing
436 donothing donothing doanything
438 let collect_iso_info =
440 let donothing r k e
= k e
in
441 let rule_elem r k e
=
442 match Ast.unwrap e
with
443 Ast.DisjRuleElem
(l
) -> k e
445 let isos = collect_all_isos.V.combiner_rule_elem e
in
446 Ast.set_isos e
isos in
448 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
449 donothing donothing donothing donothing donothing donothing donothing
451 donothing donothing donothing donothing rule_elem donothing donothing
454 (* ----------------------------------------------------------------------- *)
461 | Ast.InitialScriptRule _
| Ast.FinalScriptRule _
-> (mv
, r
)
462 | Ast.CocciRule
(nm
, rule_info
, r
, isexp
, ruletype
) ->
466 let res = disj_all.V.rebuilder_top_level x
in
467 if !Flag.track_iso_usage
468 then collect_iso_info.V.rebuilder_top_level
res
471 (mv
, Ast.CocciRule
(nm
,rule_info
,res,isexp
,ruletype
)))