4 let setify l
= (* keep first *)
5 let rec loop seen
= function
8 if List.mem x seen
then loop seen xs
else x
::(loop (x
::seen
) xs
) in
11 let disjmult2 e1 e2 k
=
13 (List.map
(function e1
-> List.map
(function e2
-> k e1 e2
) e2
) e1
)
15 let disjmult3 e1 e2 e3 k
=
21 (function e2
-> List.map
(function e3
-> k e1 e2 e3
) e3
)
25 let rec disjmult f
= function
29 let rest = disjmult f xs
in
30 disjmult2 cur rest (function cur -> function rest -> cur :: rest)
32 let disjoption f
= function
34 | Some x
-> List.map
(function x
-> Some x
) (f x
)
37 match Ast.unwrap d
with
39 List.map
(function l
-> Ast.rewrap d
(Ast.DOTS
(l
))) (disjmult f l
)
41 List.map
(function l
-> Ast.rewrap d
(Ast.CIRCLES
(l
))) (disjmult f l
)
43 List.map
(function l
-> Ast.rewrap d
(Ast.STARS
(l
))) (disjmult f l
)
46 match Ast.unwrap ft
with
48 let ty = disjtypeC
ty in
49 List.map
(function ty -> Ast.rewrap ft
(Ast.Type
(cv
,ty))) ty
50 | Ast.DisjType
(types
) -> List.concat
(List.map
disjty types
)
53 List.map
(function ty -> Ast.rewrap ft
(Ast.OptType
(ty))) ty
54 | Ast.UniqueType
(ty) ->
56 List.map
(function ty -> Ast.rewrap ft
(Ast.UniqueType
(ty))) ty
59 match Ast.unwrap bty
with
60 Ast.BaseType
(_
) | Ast.SignedT
(_
,_
) -> [bty
]
61 | Ast.Pointer
(ty,star
) ->
63 List.map
(function ty -> Ast.rewrap bty
(Ast.Pointer
(ty,star
))) ty
64 | Ast.FunctionPointer
(ty,lp1
,star
,rp1
,lp2
,params
,rp2
) ->
68 Ast.rewrap bty
(Ast.FunctionPointer
(ty,lp1
,star
,rp1
,lp2
,params
,rp2
)))
70 | Ast.FunctionType
(s
,ty,lp1
,params
,rp1
) ->
71 let ty = disjoption disjty ty in
74 Ast.rewrap bty
(Ast.FunctionType
(s
,ty,lp1
,params
,rp1
)))
76 | Ast.Array
(ty,lb
,size
,rb
) ->
77 disjmult2 (disjty ty) (disjoption disjexp size
)
78 (function ty -> function size
->
79 Ast.rewrap bty
(Ast.Array
(ty,lb
,size
,rb
)))
80 | Ast.EnumName
(_
,_
) | Ast.StructUnionName
(_
,_
) -> [bty
]
81 | Ast.StructUnionDef
(ty,lb
,decls
,rb
) ->
82 disjmult2 (disjty ty) (disjdots disjdecl decls
)
83 (function ty -> function decls
->
84 Ast.rewrap bty
(Ast.StructUnionDef
(ty,lb
,decls
,rb
)))
85 | Ast.TypeName
(_
) | Ast.MetaType
(_
,_
,_
) -> [bty
]
88 match Ast.unwrap e
with
89 Ast.Ident
(_
) | Ast.Constant
(_
) -> [e
]
90 | Ast.FunCall
(fn
,lp
,args
,rp
) ->
91 disjmult2 (disjexp fn
) (disjdots disjexp args
)
92 (function fn
-> function args
->
93 Ast.rewrap e
(Ast.FunCall
(fn
,lp
,args
,rp
)))
94 | Ast.Assignment
(left
,op
,right
,simple
) ->
95 disjmult2 (disjexp left
) (disjexp right
)
96 (function left
-> function right
->
97 Ast.rewrap e
(Ast.Assignment
(left
,op
,right
,simple
)))
98 | Ast.CondExpr
(exp1
,why
,Some exp2
,colon
,exp3
) ->
99 let res = disjmult disjexp
[exp1
;exp2
;exp3
] in
103 Ast.rewrap e
(Ast.CondExpr
(exp1
,why
,Some exp2
,colon
,exp3
))
104 | _
-> failwith
"not possible")
106 | Ast.CondExpr
(exp1
,why
,None
,colon
,exp3
) ->
107 disjmult2 (disjexp exp1
) (disjexp exp3
)
108 (function exp1
-> function exp3
->
109 Ast.rewrap e
(Ast.CondExpr
(exp1
,why
,None
,colon
,exp3
)))
110 | Ast.Postfix
(exp
,op
) ->
111 let exp = disjexp
exp in
112 List.map
(function exp -> Ast.rewrap e
(Ast.Postfix
(exp,op
))) exp
113 | Ast.Infix
(exp,op
) ->
114 let exp = disjexp
exp in
115 List.map
(function exp -> Ast.rewrap e
(Ast.Infix
(exp,op
))) exp
116 | Ast.Unary
(exp,op
) ->
117 let exp = disjexp
exp in
118 List.map
(function exp -> Ast.rewrap e
(Ast.Unary
(exp,op
))) exp
119 | Ast.Binary
(left
,op
,right
) ->
120 disjmult2 (disjexp left
) (disjexp right
)
121 (function left
-> function right
->
122 Ast.rewrap e
(Ast.Binary
(left
,op
,right
)))
123 | Ast.Nested
(exp,op
,right
) ->
124 (* disj not possible in right *)
125 let exp = disjexp
exp in
126 List.map
(function exp -> Ast.rewrap e
(Ast.Nested
(exp,op
,right
))) exp
127 | Ast.Paren
(lp
,exp,rp
) ->
128 let exp = disjexp
exp in
129 List.map
(function exp -> Ast.rewrap e
(Ast.Paren
(lp
,exp,rp
))) exp
130 | Ast.ArrayAccess
(exp1
,lb
,exp2
,rb
) ->
131 disjmult2 (disjexp exp1
) (disjexp exp2
)
132 (function exp1
-> function exp2
->
133 Ast.rewrap e
(Ast.ArrayAccess
(exp1
,lb
,exp2
,rb
)))
134 | Ast.RecordAccess
(exp,pt
,field
) ->
135 let exp = disjexp
exp in
137 (function exp -> Ast.rewrap e
(Ast.RecordAccess
(exp,pt
,field
))) exp
138 | Ast.RecordPtAccess
(exp,ar
,field
) ->
139 let exp = disjexp
exp in
141 (function exp -> Ast.rewrap e
(Ast.RecordPtAccess
(exp,ar
,field
))) exp
142 | Ast.Cast
(lp
,ty,rp
,exp) ->
143 disjmult2 (disjty ty) (disjexp
exp)
144 (function ty -> function exp -> Ast.rewrap e
(Ast.Cast
(lp
,ty,rp
,exp)))
145 | Ast.SizeOfExpr
(szf
,exp) ->
146 let exp = disjexp
exp in
147 List.map
(function exp -> Ast.rewrap e
(Ast.SizeOfExpr
(szf
,exp))) exp
148 | Ast.SizeOfType
(szf
,lp
,ty,rp
) ->
149 let ty = disjty ty in
151 (function ty -> Ast.rewrap e
(Ast.SizeOfType
(szf
,lp
,ty,rp
))) ty
153 let ty = disjty ty in
154 List.map
(function ty -> Ast.rewrap e
(Ast.TypeExp
(ty))) ty
155 | Ast.MetaErr
(_
,_
,_
,_
) | Ast.MetaExpr
(_
,_
,_
,_
,_
,_
)
156 | Ast.MetaExprList
(_
,_
,_
,_
) | Ast.EComma
(_
) -> [e
]
157 | Ast.DisjExpr
(exp_list
) ->
158 List.concat
(List.map disjexp exp_list
)
159 | Ast.NestExpr
(expr_dots
,whencode
,multi
) ->
160 (* not sure what to do here, so ambiguities still possible *)
162 | Ast.Edots
(dots
,_
) | Ast.Ecircles
(dots
,_
) | Ast.Estars
(dots
,_
) -> [e
]
164 let exp = disjexp
exp in
165 List.map
(function exp -> Ast.rewrap e
(Ast.OptExp
(exp))) exp
166 | Ast.UniqueExp
(exp) ->
167 let exp = disjexp
exp in
168 List.map
(function exp -> Ast.rewrap e
(Ast.UniqueExp
(exp))) exp
171 match Ast.unwrap p
with
172 Ast.VoidParam
(ty) -> [p
] (* void is the only possible value *)
173 | Ast.Param
(ty,id
) ->
174 let ty = disjty ty in
175 List.map
(function ty -> Ast.rewrap p
(Ast.Param
(ty,id
))) ty
176 | Ast.MetaParam
(_
,_
,_
) | Ast.MetaParamList
(_
,_
,_
,_
) | Ast.PComma
(_
) -> [p
]
177 | Ast.Pdots
(dots
) | Ast.Pcircles
(dots
) -> [p
]
178 | Ast.OptParam
(param
) ->
179 let param = disjparam
param in
180 List.map
(function param -> Ast.rewrap p
(Ast.OptParam
(param))) param
181 | Ast.UniqueParam
(param) ->
182 let param = disjparam
param in
183 List.map
(function param -> Ast.rewrap p
(Ast.UniqueParam
(param))) param
186 match Ast.unwrap i
with
187 Ast.MetaInit
(_
,_
,_
) -> [i
]
188 | Ast.InitExpr
(exp) ->
189 let exp = disjexp
exp in
190 List.map
(function exp -> Ast.rewrap i
(Ast.InitExpr
(exp))) exp
191 | Ast.InitList
(lb
,initlist
,rb
,whencode
) ->
193 (function initlist
->
194 Ast.rewrap i
(Ast.InitList
(lb
,initlist
,rb
,whencode
)))
195 (disjmult disjini initlist
)
196 | Ast.InitGccExt
(designators
,eq
,ini
) ->
197 let designators = disjmult designator
designators in
198 let ini = disjini
ini in
199 disjmult2 designators ini
200 (function designators -> function ini ->
201 Ast.rewrap i
(Ast.InitGccExt
(designators,eq
,ini)))
202 | Ast.InitGccName
(name
,eq
,ini) ->
203 let ini = disjini
ini in
205 (function ini -> Ast.rewrap i
(Ast.InitGccName
(name
,eq
,ini)))
207 | Ast.IComma
(comma
) -> [i
]
209 let ini = disjini
ini in
210 List.map
(function ini -> Ast.rewrap i
(Ast.OptIni
(ini))) ini
211 | Ast.UniqueIni
(ini) ->
212 let ini = disjini
ini in
213 List.map
(function ini -> Ast.rewrap i
(Ast.UniqueIni
(ini))) ini
215 and designator
= function
216 Ast.DesignatorField
(dot
,id
) -> [Ast.DesignatorField
(dot
,id
)]
217 | Ast.DesignatorIndex
(lb
,exp,rb
) ->
218 let exp = disjexp
exp in
219 List.map
(function exp -> Ast.DesignatorIndex
(lb
,exp,rb
)) exp
220 | Ast.DesignatorRange
(lb
,min
,dots
,max
,rb
) ->
221 disjmult2 (disjexp min
) (disjexp max
)
222 (function min
-> function max
->
223 Ast.DesignatorRange
(lb
,min
,dots
,max
,rb
))
226 match Ast.unwrap d
with
227 Ast.Init
(stg
,ty,id
,eq
,ini,sem
) ->
228 disjmult2 (disjty ty) (disjini
ini)
229 (function ty -> function ini ->
230 Ast.rewrap d
(Ast.Init
(stg
,ty,id
,eq
,ini,sem
)))
231 | Ast.UnInit
(stg
,ty,id
,sem
) ->
232 let ty = disjty ty in
233 List.map
(function ty -> Ast.rewrap d
(Ast.UnInit
(stg
,ty,id
,sem
))) ty
234 | Ast.MacroDecl
(name
,lp
,args
,rp
,sem
) ->
236 (function args
-> Ast.rewrap d
(Ast.MacroDecl
(name
,lp
,args
,rp
,sem
)))
237 (disjdots disjexp args
)
238 | Ast.TyDecl
(ty,sem
) ->
239 let ty = disjty ty in
240 List.map
(function ty -> Ast.rewrap d
(Ast.TyDecl
(ty,sem
))) ty
241 | Ast.Typedef
(stg
,ty,id
,sem
) ->
242 let ty = disjty ty in (* disj not allowed in id *)
243 List.map
(function ty -> Ast.rewrap d
(Ast.Typedef
(stg
,ty,id
,sem
))) ty
244 | Ast.DisjDecl
(decls
) -> List.concat
(List.map disjdecl decls
)
245 | Ast.Ddots
(_
,_
) | Ast.MetaDecl
(_
,_
,_
) -> [d
]
246 | Ast.OptDecl
(decl
) ->
247 let decl = disjdecl
decl in
248 List.map
(function decl -> Ast.rewrap d
(Ast.OptDecl
(decl))) decl
249 | Ast.UniqueDecl
(decl) ->
250 let decl = disjdecl
decl in
251 List.map
(function decl -> Ast.rewrap d
(Ast.UniqueDecl
(decl))) decl
253 let generic_orify_rule_elem f re
exp rebuild
=
257 Ast.rewrap re
(Ast.DisjRuleElem
(setify(List.map rebuild orexps
)))
259 let orify_rule_elem re
exp rebuild
=
260 generic_orify_rule_elem disjexp re
exp rebuild
262 let orify_rule_elem_ty = generic_orify_rule_elem disjty
263 let orify_rule_elem_param = generic_orify_rule_elem disjparam
264 let orify_rule_elem_decl = generic_orify_rule_elem disjdecl
265 let orify_rule_elem_ini = generic_orify_rule_elem disjini
267 let rec disj_rule_elem r k re
=
268 match Ast.unwrap re
with
269 Ast.FunHeader
(bef
,allminus
,fninfo
,name
,lp
,params
,rp
) ->
270 generic_orify_rule_elem (disjdots disjparam
) re params
273 (Ast.FunHeader
(bef
,allminus
,fninfo
,name
,lp
,params
,rp
)))
274 | Ast.Decl
(bef
,allminus
,decl) ->
275 orify_rule_elem_decl re
decl
276 (function decl -> Ast.rewrap re
(Ast.Decl
(bef
,allminus
,decl)))
277 | Ast.SeqStart
(brace
) -> re
278 | Ast.SeqEnd
(brace
) -> re
279 | Ast.ExprStatement
(exp,sem
) ->
280 orify_rule_elem re
exp
281 (function exp -> Ast.rewrap re
(Ast.ExprStatement
(exp,sem
)))
282 | Ast.IfHeader
(iff
,lp
,exp,rp
) ->
283 orify_rule_elem re
exp
284 (function exp -> Ast.rewrap re
(Ast.IfHeader
(iff
,lp
,exp,rp
)))
285 | Ast.Else
(els
) -> re
286 | Ast.WhileHeader
(whl
,lp
,exp,rp
) ->
287 orify_rule_elem re
exp
288 (function exp -> Ast.rewrap re
(Ast.WhileHeader
(whl
,lp
,exp,rp
)))
289 | Ast.DoHeader
(d
) -> re
290 | Ast.WhileTail
(whl
,lp
,exp,rp
,sem
) ->
291 orify_rule_elem re
exp
292 (function exp -> Ast.rewrap re
(Ast.WhileTail
(whl
,lp
,exp,rp
,sem
)))
293 | Ast.ForHeader
(fr
,lp
,e1
,sem1
,e2
,sem2
,e3
,rp
) ->
294 generic_orify_rule_elem (disjmult (disjoption disjexp
)) re
[e1
;e2
;e3
]
297 Ast.rewrap re
(Ast.ForHeader
(fr
,lp
,exp1
,sem1
,exp2
,sem2
,exp3
,rp
))
298 | _
-> failwith
"not possible")
299 | Ast.IteratorHeader
(whl
,lp
,args
,rp
) ->
300 generic_orify_rule_elem (disjdots disjexp
) re args
301 (function args
-> Ast.rewrap re
(Ast.IteratorHeader
(whl
,lp
,args
,rp
)))
302 | Ast.SwitchHeader
(switch
,lp
,exp,rp
) ->
303 orify_rule_elem re
exp
304 (function exp -> Ast.rewrap re
(Ast.SwitchHeader
(switch
,lp
,exp,rp
)))
305 | Ast.Break
(_
,_
) | Ast.Continue
(_
,_
) | Ast.Label
(_
,_
) | Ast.Goto
(_
,_
,_
)
306 | Ast.Return
(_
,_
) -> re
307 | Ast.ReturnExpr
(ret
,exp,sem
) ->
308 orify_rule_elem re
exp
309 (function exp -> Ast.rewrap re
(Ast.ReturnExpr
(ret
,exp,sem
)))
310 | Ast.MetaRuleElem
(_
,_
,_
) | Ast.MetaStmt
(_
,_
,_
,_
)
311 | Ast.MetaStmtList
(_
,_
,_
) -> re
313 orify_rule_elem re
exp (function exp -> Ast.rewrap
exp (Ast.Exp
(exp)))
315 orify_rule_elem re
exp (function exp -> Ast.rewrap
exp (Ast.TopExp
(exp)))
317 orify_rule_elem_ty re
ty (function ty -> Ast.rewrap
ty (Ast.Ty
(ty)))
318 | Ast.TopInit
(init
) ->
319 orify_rule_elem_ini re init
320 (function init
-> Ast.rewrap init
(Ast.TopInit
(init
)))
321 | Ast.Include
(inc
,s
) -> re
322 | Ast.DefineHeader
(def
,id
,params
) -> re
323 | Ast.Default
(def
,colon
) -> re
324 | Ast.Case
(case
,exp,colon
) ->
325 orify_rule_elem re
exp
326 (function exp -> Ast.rewrap re
(Ast.Case
(case
,exp,colon
)))
327 | Ast.DisjRuleElem
(l
) ->
328 (* only case lines *)
329 Ast.rewrap re
(Ast.DisjRuleElem
(setify(List.map
(disj_rule_elem r k
) l
)))
333 let donothing r k e
= k e
in
335 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
336 donothing donothing donothing donothing
337 donothing donothing donothing donothing donothing donothing donothing
338 disj_rule_elem donothing donothing donothing donothing
340 (* ----------------------------------------------------------------------- *)
341 (* collect iso information at the rule_elem level *)
343 let collect_all_isos =
345 let option_default = [] in
346 let mcode r x
= [] in
347 let donothing r k e
= Common.union_set
(Ast.get_isos e
) (k e
) in
348 let doanything r k e
= k e
in
349 V.combiner
bind option_default
350 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
351 donothing donothing donothing donothing donothing donothing donothing
352 donothing donothing donothing donothing donothing donothing donothing
355 let collect_iso_info =
357 let donothing r k e
= k e
in
358 let rule_elem r k e
=
359 match Ast.unwrap e
with
360 Ast.DisjRuleElem
(l
) -> k e
362 let isos = collect_all_isos.V.combiner_rule_elem e
in
363 Ast.set_isos e
isos in
365 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
366 donothing donothing donothing donothing donothing donothing donothing
367 donothing donothing donothing donothing rule_elem donothing donothing
370 (* ----------------------------------------------------------------------- *)
377 | Ast.InitialScriptRule _
| Ast.FinalScriptRule _
-> (mv
, r
)
378 | Ast.CocciRule
(nm
, rule_info
, r
, isexp
, ruletype
) ->
382 let res = disj_all.V.rebuilder_top_level x
in
383 if !Flag.track_iso_usage
384 then collect_iso_info.V.rebuilder_top_level
res
387 (mv
, Ast.CocciRule
(nm
,rule_info
,res,isexp
,ruletype
)))