Coccinelle release 0.2.5-rc7.
[bpt/coccinelle.git] / parsing_cocci / ast0toast.ml
CommitLineData
c491d8ee
C
1(*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
34e49164
C
25(* Arities matter for the minus slice, but not for the plus slice. *)
26
27(* + only allowed on code in a nest (in_nest = true). ? only allowed on
28rule_elems, and on subterms if the context is ? also. *)
29
30module Ast0 = Ast0_cocci
31module Ast = Ast_cocci
32module V0 = Visitor_ast0
b1b2de81 33module VT0 = Visitor_ast0_types
34e49164
C
34
35let unitary = Type_cocci.Unitary
36
37let ctr = ref 0
38let get_ctr _ =
39 let c = !ctr in
40 ctr := !ctr + 1;
41 c
42
43(* --------------------------------------------------------------------- *)
44(* Move plus tokens from the MINUS and CONTEXT structured nodes to the
45corresponding leftmost and rightmost mcodes *)
46
47let inline_mcodes =
48 let bind x y = () in
49 let option_default = () in
50 let mcode _ = () in
51 let do_nothing r k e =
52 k e;
53 let einfo = Ast0.get_info e in
54 match (Ast0.get_mcodekind e) with
55 Ast0.MINUS(replacements) ->
56 (match !replacements with
57 ([],_) -> ()
58 | replacements ->
59 let minus_try = function
60 (true,mc) ->
61 if List.for_all
62 (function
63 Ast0.MINUS(mreplacements) -> true | _ -> false)
64 mc
65 then
66 (List.iter
67 (function
68 Ast0.MINUS(mreplacements) ->
69 mreplacements := replacements
70 | _ -> ())
71 mc;
72 true)
73 else false
74 | _ -> false in
75 if not (minus_try(einfo.Ast0.attachable_start,
76 einfo.Ast0.mcode_start)
77 or
78 minus_try(einfo.Ast0.attachable_end,
79 einfo.Ast0.mcode_end))
80 then
81 failwith "minus tree should not have bad code on both sides")
82 | Ast0.CONTEXT(befaft)
83 | Ast0.MIXED(befaft) ->
84 let concat starter startinfo ender endinfo =
85 let lst =
86 match (starter,ender) with
87 ([],_) -> ender
88 | (_,[]) -> starter
89 | _ ->
90 if startinfo.Ast0.tline_end = endinfo.Ast0.tline_start
91 then (* put them in the same inner list *)
92 let last = List.hd (List.rev starter) in
93 let butlast = List.rev(List.tl(List.rev starter)) in
94 butlast @ (last@(List.hd ender)) :: (List.tl ender)
95 else starter @ ender in
96 (lst,
97 {endinfo with Ast0.tline_start = startinfo.Ast0.tline_start}) in
951c7801 98 let attach_bef bef beforeinfo befit = function
34e49164
C
99 (true,mcl) ->
100 List.iter
101 (function
102 Ast0.MINUS(mreplacements) ->
103 let (mrepl,tokeninfo) = !mreplacements in
104 mreplacements := concat bef beforeinfo mrepl tokeninfo
105 | Ast0.CONTEXT(mbefaft) ->
106 (match !mbefaft with
951c7801 107 (Ast.BEFORE(mbef,it),mbeforeinfo,a) ->
34e49164
C
108 let (newbef,newinfo) =
109 concat bef beforeinfo mbef mbeforeinfo in
951c7801
C
110 let it = Ast.lub_count befit it in
111 mbefaft := (Ast.BEFORE(newbef,it),newinfo,a)
112 | (Ast.AFTER(maft,it),_,a) ->
113 let it = Ast.lub_count befit it in
34e49164 114 mbefaft :=
951c7801
C
115 (Ast.BEFOREAFTER(bef,maft,it),beforeinfo,a)
116 | (Ast.BEFOREAFTER(mbef,maft,it),mbeforeinfo,a) ->
34e49164
C
117 let (newbef,newinfo) =
118 concat bef beforeinfo mbef mbeforeinfo in
951c7801 119 let it = Ast.lub_count befit it in
34e49164 120 mbefaft :=
951c7801 121 (Ast.BEFOREAFTER(newbef,maft,it),newinfo,a)
34e49164 122 | (Ast.NOTHING,_,a) ->
951c7801
C
123 mbefaft :=
124 (Ast.BEFORE(bef,befit),beforeinfo,a))
34e49164
C
125 | _ -> failwith "unexpected annotation")
126 mcl
127 | _ ->
978fd7e5 128 Printf.printf "before %s\n" (Dumper.dump bef);
34e49164 129 failwith
978fd7e5 130 "context tree should not have bad code before" in
951c7801 131 let attach_aft aft afterinfo aftit = function
34e49164
C
132 (true,mcl) ->
133 List.iter
134 (function
135 Ast0.MINUS(mreplacements) ->
136 let (mrepl,tokeninfo) = !mreplacements in
137 mreplacements := concat mrepl tokeninfo aft afterinfo
138 | Ast0.CONTEXT(mbefaft) ->
139 (match !mbefaft with
951c7801
C
140 (Ast.BEFORE(mbef,it),b,_) ->
141 let it = Ast.lub_count aftit it in
34e49164 142 mbefaft :=
951c7801
C
143 (Ast.BEFOREAFTER(mbef,aft,it),b,afterinfo)
144 | (Ast.AFTER(maft,it),b,mafterinfo) ->
34e49164
C
145 let (newaft,newinfo) =
146 concat maft mafterinfo aft afterinfo in
951c7801
C
147 let it = Ast.lub_count aftit it in
148 mbefaft := (Ast.AFTER(newaft,it),b,newinfo)
149 | (Ast.BEFOREAFTER(mbef,maft,it),b,mafterinfo) ->
34e49164
C
150 let (newaft,newinfo) =
151 concat maft mafterinfo aft afterinfo in
951c7801 152 let it = Ast.lub_count aftit it in
34e49164 153 mbefaft :=
951c7801 154 (Ast.BEFOREAFTER(mbef,newaft,it),b,newinfo)
34e49164 155 | (Ast.NOTHING,b,_) ->
951c7801 156 mbefaft := (Ast.AFTER(aft,aftit),b,afterinfo))
34e49164
C
157 | _ -> failwith "unexpected annotation")
158 mcl
159 | _ ->
160 failwith
978fd7e5 161 "context tree should not have bad code after" in
34e49164 162 (match !befaft with
951c7801
C
163 (Ast.BEFORE(bef,it),beforeinfo,_) ->
164 attach_bef bef beforeinfo it
34e49164 165 (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start)
951c7801
C
166 | (Ast.AFTER(aft,it),_,afterinfo) ->
167 attach_aft aft afterinfo it
34e49164 168 (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end)
951c7801
C
169 | (Ast.BEFOREAFTER(bef,aft,it),beforeinfo,afterinfo) ->
170 attach_bef bef beforeinfo it
34e49164 171 (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start);
951c7801 172 attach_aft aft afterinfo it
34e49164
C
173 (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end)
174 | (Ast.NOTHING,_,_) -> ())
951c7801 175 | Ast0.PLUS _ -> () in
b1b2de81 176 V0.flat_combiner bind option_default
34e49164 177 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
faf9a90c 178 mcode mcode
34e49164
C
179 do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
180 do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
181 do_nothing do_nothing do_nothing
182
183(* --------------------------------------------------------------------- *)
184(* For function declarations. Can't use the mcode at the root, because that
185might be mixed when the function contains ()s, where agglomeration of -s is
186not possible. *)
187
188let check_allminus =
189 let donothing r k e = k e in
190 let bind x y = x && y in
191 let option_default = true in
708f4980 192 let mcode (_,_,_,mc,_,_) =
34e49164
C
193 match mc with
194 Ast0.MINUS(r) -> let (plusses,_) = !r in plusses = []
195 | _ -> false in
196
197 (* special case for disj *)
d3f655c6
C
198 let ident r k e =
199 match Ast0.unwrap e with
200 Ast0.DisjId(starter,id_list,mids,ender) ->
201 List.for_all r.VT0.combiner_rec_ident id_list
202 | _ -> k e in
203
34e49164
C
204 let expression r k e =
205 match Ast0.unwrap e with
206 Ast0.DisjExpr(starter,expr_list,mids,ender) ->
b1b2de81 207 List.for_all r.VT0.combiner_rec_expression expr_list
34e49164
C
208 | _ -> k e in
209
210 let declaration r k e =
211 match Ast0.unwrap e with
212 Ast0.DisjDecl(starter,decls,mids,ender) ->
b1b2de81 213 List.for_all r.VT0.combiner_rec_declaration decls
34e49164
C
214 | _ -> k e in
215
216 let typeC r k e =
217 match Ast0.unwrap e with
218 Ast0.DisjType(starter,decls,mids,ender) ->
b1b2de81 219 List.for_all r.VT0.combiner_rec_typeC decls
34e49164
C
220 | _ -> k e in
221
222 let statement r k e =
223 match Ast0.unwrap e with
224 Ast0.Disj(starter,statement_dots_list,mids,ender) ->
b1b2de81 225 List.for_all r.VT0.combiner_rec_statement_dots statement_dots_list
34e49164
C
226 | _ -> k e in
227
fc1ad971
C
228 let case_line r k e =
229 match Ast0.unwrap e with
230 Ast0.DisjCase(starter,case_lines,mids,ender) ->
231 List.for_all r.VT0.combiner_rec_case_line case_lines
232 | _ -> k e in
233
b1b2de81 234 V0.flat_combiner bind option_default
34e49164 235 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
faf9a90c 236 mcode mcode
34e49164 237 donothing donothing donothing donothing donothing donothing
d3f655c6 238 ident expression typeC donothing donothing declaration
fc1ad971 239 statement case_line donothing
faf9a90c 240
34e49164
C
241(* --------------------------------------------------------------------- *)
242(* --------------------------------------------------------------------- *)
faf9a90c 243
34e49164
C
244let get_option fn = function
245 None -> None
246 | Some x -> Some (fn x)
247
248(* --------------------------------------------------------------------- *)
249(* --------------------------------------------------------------------- *)
250(* Mcode *)
faf9a90c 251
34e49164 252let convert_info info =
0708f913
C
253 let strings_to_s l =
254 List.map
255 (function (s,info) -> (s,info.Ast0.line_start,info.Ast0.column))
256 l in
257 { Ast.line = info.Ast0.pos_info.Ast0.line_start;
258 Ast.column = info.Ast0.pos_info.Ast0.column;
259 Ast.strbef = strings_to_s info.Ast0.strings_before;
708f4980 260 Ast.straft = strings_to_s info.Ast0.strings_after;}
34e49164 261
708f4980 262let convert_mcodekind adj = function
34e49164 263 Ast0.MINUS(replacements) ->
faf9a90c 264 let (replacements,_) = !replacements in
708f4980 265 Ast.MINUS(Ast.NoPos,[],adj,replacements)
951c7801 266 | Ast0.PLUS count -> Ast.PLUS count
34e49164
C
267 | Ast0.CONTEXT(befaft) ->
268 let (befaft,_,_) = !befaft in Ast.CONTEXT(Ast.NoPos,befaft)
269 | Ast0.MIXED(_) -> failwith "not possible for mcode"
270
708f4980 271let pos_mcode(term,_,info,mcodekind,pos,adj) =
34e49164 272 (* avoids a recursion problem *)
708f4980 273 (term,convert_info info,convert_mcodekind adj mcodekind,Ast.NoMetaPos)
34e49164 274
708f4980 275let mcode (term,_,info,mcodekind,pos,adj) =
34e49164
C
276 let pos =
277 match !pos with
278 Ast0.MetaPos(pos,constraints,per) ->
279 Ast.MetaPos(pos_mcode pos,constraints,per,unitary,false)
280 | _ -> Ast.NoMetaPos in
708f4980 281 (term,convert_info info,convert_mcodekind adj mcodekind,pos)
34e49164
C
282
283(* --------------------------------------------------------------------- *)
284(* Dots *)
285let wrap ast line isos =
286 {(Ast.make_term ast) with Ast.node_line = line;
287 Ast.iso_info = isos}
288
289let rewrap ast0 isos ast =
0708f913 290 wrap ast ((Ast0.get_info ast0).Ast0.pos_info.Ast0.line_start) isos
34e49164
C
291
292let no_isos = []
293
294(* no isos on tokens *)
295let tokenwrap (_,info,_,_) s ast = wrap ast info.Ast.line no_isos
296let iso_tokenwrap (_,info,_,_) s ast iso = wrap ast info.Ast.line iso
297
298let dots fn d =
299 rewrap d no_isos
300 (match Ast0.unwrap d with
301 Ast0.DOTS(x) -> Ast.DOTS(List.map fn x)
302 | Ast0.CIRCLES(x) -> Ast.CIRCLES(List.map fn x)
303 | Ast0.STARS(x) -> Ast.STARS(List.map fn x))
304
c491d8ee
C
305(* commas in dotted lists, here due to polymorphism restrictions *)
306
307let add_comma is_comma make_comma itemlist =
308 match Ast0.unwrap itemlist with
309 Ast0.DOTS(x) ->
310 (match List.rev x with
311 [] -> itemlist
312 | e::es ->
313 if is_comma e
314 then itemlist
315 else
316 let comma =
317 match Ast0.get_mcodekind e with
318 Ast0.MINUS(_) -> (Ast0.make_minus_mcode ",")
319 | _ -> (Ast0.make_mcode ",") in
320 Ast0.rewrap itemlist
321 (Ast0.DOTS
322 (List.rev (Ast0.rewrap e (make_comma comma) :: (e::es)))))
323 | _ -> failwith "not possible"
324
325let add_exp_comma =
326 add_comma
327 (function x -> match Ast0.unwrap x with Ast0.EComma _ -> true | _ -> false)
328 (function x -> Ast0.EComma x)
329
330and add_init_comma =
331 add_comma
332 (function x -> match Ast0.unwrap x with Ast0.IComma _ -> true | _ -> false)
333 (function x -> Ast0.IComma x)
334
34e49164
C
335(* --------------------------------------------------------------------- *)
336(* Identifier *)
337
338let rec do_isos l = List.map (function (nm,x) -> (nm,anything x)) l
339
340and ident i =
341 rewrap i (do_isos (Ast0.get_iso i))
342 (match Ast0.unwrap i with
d3f655c6
C
343 Ast0.Id(name) -> Ast.Id(mcode name)
344 | Ast0.DisjId(_,id_list,_,_) ->
345 Ast.DisjId(List.map ident id_list)
346 | Ast0.MetaId(name,constraints,_) ->
347 Ast.MetaId(mcode name,constraints,unitary,false)
348 | Ast0.MetaFunc(name,constraints,_) ->
349 Ast.MetaFunc(mcode name,constraints,unitary,false)
350 | Ast0.MetaLocalFunc(name,constraints,_) ->
351 Ast.MetaLocalFunc(mcode name,constraints,unitary,false)
352 | Ast0.OptIdent(id) -> Ast.OptIdent(ident id)
353 | Ast0.UniqueIdent(id) -> Ast.UniqueIdent(ident id))
34e49164
C
354
355(* --------------------------------------------------------------------- *)
356(* Expression *)
357
358and expression e =
359 let e1 =
360 rewrap e (do_isos (Ast0.get_iso e))
361 (match Ast0.unwrap e with
362 Ast0.Ident(id) -> Ast.Ident(ident id)
363 | Ast0.Constant(const) ->
364 Ast.Constant(mcode const)
365 | Ast0.FunCall(fn,lp,args,rp) ->
366 let fn = expression fn in
367 let lp = mcode lp in
368 let args = dots expression args in
369 let rp = mcode rp in
370 Ast.FunCall(fn,lp,args,rp)
371 | Ast0.Assignment(left,op,right,simple) ->
372 Ast.Assignment(expression left,mcode op,expression right,simple)
373 | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
374 let exp1 = expression exp1 in
375 let why = mcode why in
376 let exp2 = get_option expression exp2 in
377 let colon = mcode colon in
378 let exp3 = expression exp3 in
379 Ast.CondExpr(exp1,why,exp2,colon,exp3)
380 | Ast0.Postfix(exp,op) ->
381 Ast.Postfix(expression exp,mcode op)
382 | Ast0.Infix(exp,op) ->
383 Ast.Infix(expression exp,mcode op)
384 | Ast0.Unary(exp,op) ->
385 Ast.Unary(expression exp,mcode op)
386 | Ast0.Binary(left,op,right) ->
387 Ast.Binary(expression left,mcode op,expression right)
388 | Ast0.Nested(left,op,right) ->
389 Ast.Nested(expression left,mcode op,expression right)
390 | Ast0.Paren(lp,exp,rp) ->
391 Ast.Paren(mcode lp,expression exp,mcode rp)
392 | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
393 Ast.ArrayAccess(expression exp1,mcode lb,expression exp2,mcode rb)
394 | Ast0.RecordAccess(exp,pt,field) ->
395 Ast.RecordAccess(expression exp,mcode pt,ident field)
396 | Ast0.RecordPtAccess(exp,ar,field) ->
397 Ast.RecordPtAccess(expression exp,mcode ar,ident field)
398 | Ast0.Cast(lp,ty,rp,exp) ->
399 Ast.Cast(mcode lp,typeC ty,mcode rp,expression exp)
400 | Ast0.SizeOfExpr(szf,exp) ->
401 Ast.SizeOfExpr(mcode szf,expression exp)
402 | Ast0.SizeOfType(szf,lp,ty,rp) ->
403 Ast.SizeOfType(mcode szf, mcode lp,typeC ty,mcode rp)
404 | Ast0.TypeExp(ty) -> Ast.TypeExp(typeC ty)
951c7801
C
405 | Ast0.MetaErr(name,cstrts,_) ->
406 Ast.MetaErr(mcode name,constraints cstrts,unitary,false)
407 | Ast0.MetaExpr(name,cstrts,ty,form,_) ->
408 Ast.MetaExpr(mcode name,constraints cstrts,unitary,ty,form,false)
88e71198
C
409 | Ast0.MetaExprList(name,lenname,_) ->
410 Ast.MetaExprList(mcode name,do_lenname lenname,unitary,false)
34e49164 411 | Ast0.EComma(cm) -> Ast.EComma(mcode cm)
978fd7e5
C
412 | Ast0.DisjExpr(_,exps,_,_) ->
413 Ast.DisjExpr(List.map expression exps)
5636bb2c
C
414 | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) ->
415 let starter = mcode starter in
34e49164 416 let whencode = get_option expression whencode in
5636bb2c
C
417 let ender = mcode ender in
418 Ast.NestExpr(starter,dots expression exp_dots,ender,whencode,multi)
34e49164
C
419 | Ast0.Edots(dots,whencode) ->
420 let dots = mcode dots in
421 let whencode = get_option expression whencode in
422 Ast.Edots(dots,whencode)
423 | Ast0.Ecircles(dots,whencode) ->
424 let dots = mcode dots in
425 let whencode = get_option expression whencode in
426 Ast.Ecircles(dots,whencode)
427 | Ast0.Estars(dots,whencode) ->
428 let dots = mcode dots in
429 let whencode = get_option expression whencode in
430 Ast.Estars(dots,whencode)
431 | Ast0.OptExp(exp) -> Ast.OptExp(expression exp)
432 | Ast0.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in
433 if Ast0.get_test_exp e then Ast.set_test_exp e1 else e1
434
435and expression_dots ed = dots expression ed
faf9a90c 436
951c7801
C
437and constraints c =
438 match c with
439 Ast0.NoConstraint -> Ast.NoConstraint
440 | Ast0.NotIdCstrt idctrt -> Ast.NotIdCstrt idctrt
441 | Ast0.NotExpCstrt exps -> Ast.NotExpCstrt (List.map expression exps)
5636bb2c 442 | Ast0.SubExpCstrt ids -> Ast.SubExpCstrt ids
951c7801 443
88e71198
C
444and do_lenname = function
445 Ast0.MetaListLen(nm) -> Ast.MetaListLen(mcode nm,unitary,false)
446 | Ast0.CstListLen n -> Ast.CstListLen n
447 | Ast0.AnyListLen -> Ast.AnyListLen
448
34e49164
C
449(* --------------------------------------------------------------------- *)
450(* Types *)
451
faf9a90c
C
452and rewrap_iso t t1 = rewrap t (do_isos (Ast0.get_iso t)) t1
453
34e49164
C
454and typeC t =
455 rewrap t (do_isos (Ast0.get_iso t))
456 (match Ast0.unwrap t with
457 Ast0.ConstVol(cv,ty) ->
458 let rec collect_disjs t =
459 match Ast0.unwrap t with
460 Ast0.DisjType(_,types,_,_) ->
461 if Ast0.get_iso t = []
462 then List.concat (List.map collect_disjs types)
463 else failwith "unexpected iso on a disjtype"
464 | _ -> [t] in
465 let res =
466 List.map
467 (function ty ->
468 Ast.Type
faf9a90c 469 (Some (mcode cv),rewrap_iso ty (base_typeC ty)))
34e49164
C
470 (collect_disjs ty) in
471 (* one could worry that isos are lost because we flatten the
472 disjunctions. but there should not be isos on the disjunctions
473 themselves. *)
474 (match res with
475 [ty] -> ty
476 | types -> Ast.DisjType(List.map (rewrap t no_isos) types))
faf9a90c 477 | Ast0.BaseType(_) | Ast0.Signed(_,_) | Ast0.Pointer(_,_)
34e49164 478 | Ast0.FunctionPointer(_,_,_,_,_,_,_) | Ast0.FunctionType(_,_,_,_)
faf9a90c 479 | Ast0.Array(_,_,_,_) | Ast0.EnumName(_,_) | Ast0.StructUnionName(_,_)
c491d8ee
C
480 | Ast0.StructUnionDef(_,_,_,_) | Ast0.EnumDef(_,_,_,_)
481 | Ast0.TypeName(_) | Ast0.MetaType(_,_) ->
34e49164
C
482 Ast.Type(None,rewrap t no_isos (base_typeC t))
483 | Ast0.DisjType(_,types,_,_) -> Ast.DisjType(List.map typeC types)
484 | Ast0.OptType(ty) -> Ast.OptType(typeC ty)
485 | Ast0.UniqueType(ty) -> Ast.UniqueType(typeC ty))
faf9a90c 486
34e49164
C
487and base_typeC t =
488 match Ast0.unwrap t with
faf9a90c
C
489 Ast0.BaseType(ty,strings) -> Ast.BaseType(ty,List.map mcode strings)
490 | Ast0.Signed(sgn,ty) ->
491 Ast.SignedT(mcode sgn,
492 get_option (function x -> rewrap_iso x (base_typeC x)) ty)
34e49164
C
493 | Ast0.Pointer(ty,star) -> Ast.Pointer(typeC ty,mcode star)
494 | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
495 Ast.FunctionPointer
496 (typeC ty,mcode lp1,mcode star,mcode rp1,
497 mcode lp2,parameter_list params,mcode rp2)
498 | Ast0.FunctionType(ret,lp,params,rp) ->
b1b2de81 499 let allminus = check_allminus.VT0.combiner_rec_typeC t in
34e49164
C
500 Ast.FunctionType
501 (allminus,get_option typeC ret,mcode lp,
502 parameter_list params,mcode rp)
503 | Ast0.Array(ty,lb,size,rb) ->
504 Ast.Array(typeC ty,mcode lb,get_option expression size,mcode rb)
faf9a90c 505 | Ast0.EnumName(kind,name) ->
c491d8ee
C
506 Ast.EnumName(mcode kind,get_option ident name)
507 | Ast0.EnumDef(ty,lb,ids,rb) ->
508 let ids = add_exp_comma ids in
509 Ast.EnumDef(typeC ty,mcode lb,dots expression ids,mcode rb)
34e49164
C
510 | Ast0.StructUnionName(kind,name) ->
511 Ast.StructUnionName(mcode kind,get_option ident name)
512 | Ast0.StructUnionDef(ty,lb,decls,rb) ->
513 Ast.StructUnionDef(typeC ty,mcode lb,
514 dots declaration decls,
515 mcode rb)
516 | Ast0.TypeName(name) -> Ast.TypeName(mcode name)
517 | Ast0.MetaType(name,_) ->
518 Ast.MetaType(mcode name,unitary,false)
519 | _ -> failwith "ast0toast: unexpected type"
faf9a90c 520
34e49164
C
521(* --------------------------------------------------------------------- *)
522(* Variable declaration *)
523(* Even if the Cocci program specifies a list of declarations, they are
524 split out into multiple declarations of a single variable each. *)
faf9a90c 525
34e49164
C
526and declaration d =
527 rewrap d (do_isos (Ast0.get_iso d))
528 (match Ast0.unwrap d with
413ffc02
C
529 Ast0.MetaDecl(name,_) -> Ast.MetaDecl(mcode name,unitary,false)
530 | Ast0.MetaField(name,_) -> Ast.MetaField(mcode name,unitary,false)
531 | Ast0.Init(stg,ty,id,eq,ini,sem) ->
34e49164
C
532 let stg = get_option mcode stg in
533 let ty = typeC ty in
534 let id = ident id in
535 let eq = mcode eq in
536 let ini = initialiser ini in
537 let sem = mcode sem in
538 Ast.Init(stg,ty,id,eq,ini,sem)
539 | Ast0.UnInit(stg,ty,id,sem) ->
540 (match Ast0.unwrap ty with
541 Ast0.FunctionType(tyx,lp1,params,rp1) ->
b1b2de81 542 let allminus = check_allminus.VT0.combiner_rec_declaration d in
34e49164
C
543 Ast.UnInit(get_option mcode stg,
544 rewrap ty (do_isos (Ast0.get_iso ty))
545 (Ast.Type
546 (None,
547 rewrap ty no_isos
548 (Ast.FunctionType
549 (allminus,get_option typeC tyx,mcode lp1,
550 parameter_list params,mcode rp1)))),
551 ident id,mcode sem)
552 | _ -> Ast.UnInit(get_option mcode stg,typeC ty,ident id,mcode sem))
553 | Ast0.MacroDecl(name,lp,args,rp,sem) ->
554 let name = ident name in
555 let lp = mcode lp in
556 let args = dots expression args in
557 let rp = mcode rp in
558 let sem = mcode sem in
559 Ast.MacroDecl(name,lp,args,rp,sem)
560 | Ast0.TyDecl(ty,sem) -> Ast.TyDecl(typeC ty,mcode sem)
561 | Ast0.Typedef(stg,ty,id,sem) ->
562 let id = typeC id in
563 (match Ast.unwrap id with
564 Ast.Type(None,id) -> (* only MetaType or Id *)
565 Ast.Typedef(mcode stg,typeC ty,id,mcode sem)
566 | _ -> failwith "bad typedef")
567 | Ast0.DisjDecl(_,decls,_,_) -> Ast.DisjDecl(List.map declaration decls)
568 | Ast0.Ddots(dots,whencode) ->
569 let dots = mcode dots in
570 let whencode = get_option declaration whencode in
571 Ast.Ddots(dots,whencode)
572 | Ast0.OptDecl(decl) -> Ast.OptDecl(declaration decl)
573 | Ast0.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl))
574
575and declaration_dots l = dots declaration l
576
577(* --------------------------------------------------------------------- *)
578(* Initialiser *)
579
580and strip_idots initlist =
90aeb998
C
581 let isminus mc =
582 match Ast0.get_mcode_mcodekind mc with
583 Ast0.MINUS _ -> true
584 | _ -> false in
34e49164 585 match Ast0.unwrap initlist with
c491d8ee
C
586 Ast0.DOTS(l) ->
587 let l =
588 match List.rev l with
589 [] | [_] -> l
590 | x::y::xs ->
591 (match (Ast0.unwrap x,Ast0.unwrap y) with
592 (Ast0.IComma _,Ast0.Idots _) ->
593 (* drop comma that was added by add_comma *)
594 List.rev (y::xs)
595 | _ -> l) in
90aeb998 596 let (whencode,init,dotinfo) =
c491d8ee
C
597 let rec loop = function
598 [] -> ([],[],[])
599 | x::rest ->
600 (match Ast0.unwrap x with
34e49164 601 Ast0.Idots(dots,Some whencode) ->
c491d8ee
C
602 let (restwhen,restinit,dotinfo) = loop rest in
603 (whencode :: restwhen, restinit,
90aeb998 604 (isminus dots)::dotinfo)
c491d8ee
C
605 | Ast0.Idots(dots,None) ->
606 let (restwhen,restinit,dotinfo) = loop rest in
607 (restwhen, restinit, (isminus dots)::dotinfo)
608 | _ ->
609 let (restwhen,restinit,dotinfo) = loop rest in
610 (restwhen,x::restinit,dotinfo)) in
611 loop l in
90aeb998
C
612 let allminus =
613 if List.for_all (function x -> not x) dotinfo
614 then false (* false if no dots *)
615 else
616 if List.for_all (function x -> x) dotinfo
617 then true
618 else failwith "inconsistent annotations on initialiser list dots" in
c491d8ee 619 (whencode, init, allminus)
34e49164
C
620 | Ast0.CIRCLES(x) | Ast0.STARS(x) -> failwith "not possible for an initlist"
621
622and initialiser i =
623 rewrap i no_isos
624 (match Ast0.unwrap i with
113803cf
C
625 Ast0.MetaInit(name,_) -> Ast.MetaInit(mcode name,unitary,false)
626 | Ast0.InitExpr(exp) -> Ast.InitExpr(expression exp)
c491d8ee
C
627 | Ast0.InitList(lb,initlist,rb,true) ->
628 let initlist = add_init_comma initlist in
629 Ast.ArInitList(mcode lb,dots initialiser initlist,mcode rb)
630 | Ast0.InitList(lb,initlist,rb,false) ->
631 let initlist = add_init_comma initlist in
90aeb998 632 let (whencode,initlist,allminus) = strip_idots initlist in
c491d8ee
C
633 Ast.StrInitList
634 (allminus,mcode lb,List.map initialiser initlist,mcode rb,
635 List.map initialiser whencode)
113803cf
C
636 | Ast0.InitGccExt(designators,eq,ini) ->
637 Ast.InitGccExt(List.map designator designators,mcode eq,
638 initialiser ini)
34e49164
C
639 | Ast0.InitGccName(name,eq,ini) ->
640 Ast.InitGccName(ident name,mcode eq,initialiser ini)
34e49164 641 | Ast0.IComma(comma) -> Ast.IComma(mcode comma)
c491d8ee
C
642 | Ast0.Idots(dots,whencode) ->
643 let dots = mcode dots in
644 let whencode = get_option initialiser whencode in
645 Ast.Idots(dots,whencode)
34e49164
C
646 | Ast0.OptIni(ini) -> Ast.OptIni(initialiser ini)
647 | Ast0.UniqueIni(ini) -> Ast.UniqueIni(initialiser ini))
648
113803cf
C
649and designator = function
650 Ast0.DesignatorField(dot,id) -> Ast.DesignatorField(mcode dot,ident id)
651 | Ast0.DesignatorIndex(lb,exp,rb) ->
652 Ast.DesignatorIndex(mcode lb, expression exp, mcode rb)
653 | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
654 Ast.DesignatorRange(mcode lb,expression min,mcode dots,expression max,
655 mcode rb)
656
34e49164
C
657(* --------------------------------------------------------------------- *)
658(* Parameter *)
faf9a90c 659
34e49164
C
660and parameterTypeDef p =
661 rewrap p no_isos
662 (match Ast0.unwrap p with
663 Ast0.VoidParam(ty) -> Ast.VoidParam(typeC ty)
664 | Ast0.Param(ty,id) -> Ast.Param(typeC ty,get_option ident id)
665 | Ast0.MetaParam(name,_) ->
666 Ast.MetaParam(mcode name,unitary,false)
88e71198
C
667 | Ast0.MetaParamList(name,lenname,_) ->
668 Ast.MetaParamList(mcode name,do_lenname lenname,unitary,false)
34e49164
C
669 | Ast0.PComma(cm) -> Ast.PComma(mcode cm)
670 | Ast0.Pdots(dots) -> Ast.Pdots(mcode dots)
671 | Ast0.Pcircles(dots) -> Ast.Pcircles(mcode dots)
672 | Ast0.OptParam(param) -> Ast.OptParam(parameterTypeDef param)
673 | Ast0.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param))
674
675and parameter_list l = dots parameterTypeDef l
676
677(* --------------------------------------------------------------------- *)
678(* Top-level code *)
679
680and statement s =
681 let rec statement seqible s =
682 let rewrap_stmt ast0 ast =
683 let befaft =
684 match Ast0.get_dots_bef_aft s with
685 Ast0.NoDots -> Ast.NoDots
686 | Ast0.DroppingBetweenDots s ->
687 Ast.DroppingBetweenDots (statement seqible s,get_ctr())
688 | Ast0.AddingBetweenDots s ->
689 Ast.AddingBetweenDots (statement seqible s,get_ctr()) in
690 Ast.set_dots_bef_aft befaft (rewrap ast0 no_isos ast) in
691 let rewrap_rule_elem ast0 ast =
692 rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in
693 rewrap_stmt s
694 (match Ast0.unwrap s with
695 Ast0.Decl((_,bef),decl) ->
696 Ast.Atomic(rewrap_rule_elem s
708f4980 697 (Ast.Decl(convert_mcodekind (-1) bef,
b1b2de81 698 check_allminus.VT0.combiner_rec_statement s,
34e49164 699 declaration decl)))
faf9a90c 700 | Ast0.Seq(lbrace,body,rbrace) ->
34e49164 701 let lbrace = mcode lbrace in
708f4980 702 let body = dots (statement seqible) body in
34e49164
C
703 let rbrace = mcode rbrace in
704 Ast.Seq(iso_tokenwrap lbrace s (Ast.SeqStart(lbrace))
705 (do_isos (Ast0.get_iso s)),
708f4980 706 body,
34e49164
C
707 tokenwrap rbrace s (Ast.SeqEnd(rbrace)))
708 | Ast0.ExprStatement(exp,sem) ->
709 Ast.Atomic(rewrap_rule_elem s
710 (Ast.ExprStatement(expression exp,mcode sem)))
711 | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) ->
712 Ast.IfThen
713 (rewrap_rule_elem s
714 (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)),
715 statement Ast.NotSequencible branch,
708f4980 716 ([],[],[],convert_mcodekind (-1) aft))
34e49164
C
717 | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) ->
718 let els = mcode els in
719 Ast.IfThenElse
720 (rewrap_rule_elem s
721 (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)),
722 statement Ast.NotSequencible branch1,
723 tokenwrap els s (Ast.Else(els)),
724 statement Ast.NotSequencible branch2,
708f4980 725 ([],[],[],convert_mcodekind (-1) aft))
34e49164
C
726 | Ast0.While(wh,lp,exp,rp,body,(_,aft)) ->
727 Ast.While(rewrap_rule_elem s
728 (Ast.WhileHeader
729 (mcode wh,mcode lp,expression exp,mcode rp)),
730 statement Ast.NotSequencible body,
708f4980 731 ([],[],[],convert_mcodekind (-1) aft))
34e49164
C
732 | Ast0.Do(d,body,wh,lp,exp,rp,sem) ->
733 let wh = mcode wh in
734 Ast.Do(rewrap_rule_elem s (Ast.DoHeader(mcode d)),
735 statement Ast.NotSequencible body,
736 tokenwrap wh s
737 (Ast.WhileTail(wh,mcode lp,expression exp,mcode rp,
738 mcode sem)))
739 | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) ->
740 let fr = mcode fr in
741 let lp = mcode lp in
742 let exp1 = get_option expression exp1 in
743 let sem1 = mcode sem1 in
744 let exp2 = get_option expression exp2 in
745 let sem2= mcode sem2 in
746 let exp3 = get_option expression exp3 in
747 let rp = mcode rp in
748 let body = statement Ast.NotSequencible body in
749 Ast.For(rewrap_rule_elem s
750 (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)),
708f4980 751 body,([],[],[],convert_mcodekind (-1) aft))
34e49164
C
752 | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) ->
753 Ast.Iterator(rewrap_rule_elem s
754 (Ast.IteratorHeader
755 (ident nm,mcode lp,
756 dots expression args,
757 mcode rp)),
758 statement Ast.NotSequencible body,
708f4980 759 ([],[],[],convert_mcodekind (-1) aft))
fc1ad971 760 | Ast0.Switch(switch,lp,exp,rp,lb,decls,cases,rb) ->
34e49164
C
761 let switch = mcode switch in
762 let lp = mcode lp in
763 let exp = expression exp in
764 let rp = mcode rp in
765 let lb = mcode lb in
fc1ad971 766 let decls = dots (statement seqible) decls in
34e49164
C
767 let cases = List.map case_line (Ast0.undots cases) in
768 let rb = mcode rb in
769 Ast.Switch(rewrap_rule_elem s (Ast.SwitchHeader(switch,lp,exp,rp)),
770 tokenwrap lb s (Ast.SeqStart(lb)),
fc1ad971 771 decls,cases,
34e49164
C
772 tokenwrap rb s (Ast.SeqEnd(rb)))
773 | Ast0.Break(br,sem) ->
774 Ast.Atomic(rewrap_rule_elem s (Ast.Break(mcode br,mcode sem)))
775 | Ast0.Continue(cont,sem) ->
776 Ast.Atomic(rewrap_rule_elem s (Ast.Continue(mcode cont,mcode sem)))
777 | Ast0.Label(l,dd) ->
778 Ast.Atomic(rewrap_rule_elem s (Ast.Label(ident l,mcode dd)))
779 | Ast0.Goto(goto,l,sem) ->
780 Ast.Atomic
781 (rewrap_rule_elem s (Ast.Goto(mcode goto,ident l,mcode sem)))
782 | Ast0.Return(ret,sem) ->
783 Ast.Atomic(rewrap_rule_elem s (Ast.Return(mcode ret,mcode sem)))
784 | Ast0.ReturnExpr(ret,exp,sem) ->
785 Ast.Atomic
786 (rewrap_rule_elem s
787 (Ast.ReturnExpr(mcode ret,expression exp,mcode sem)))
788 | Ast0.MetaStmt(name,_) ->
789 Ast.Atomic(rewrap_rule_elem s
790 (Ast.MetaStmt(mcode name,unitary,seqible,false)))
791 | Ast0.MetaStmtList(name,_) ->
792 Ast.Atomic(rewrap_rule_elem s
793 (Ast.MetaStmtList(mcode name,unitary,false)))
794 | Ast0.TopExp(exp) ->
795 Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp)))
796 | Ast0.Exp(exp) ->
797 Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp)))
1be43e12
C
798 | Ast0.TopInit(init) ->
799 Ast.Atomic(rewrap_rule_elem s (Ast.TopInit(initialiser init)))
34e49164
C
800 | Ast0.Ty(ty) ->
801 Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty)))
802 | Ast0.Disj(_,rule_elem_dots_list,_,_) ->
803 Ast.Disj(List.map (function x -> statement_dots seqible x)
804 rule_elem_dots_list)
5636bb2c 805 | Ast0.Nest(starter,rule_elem_dots,ender,whn,multi) ->
34e49164 806 Ast.Nest
5636bb2c
C
807 (mcode starter,statement_dots Ast.Sequencible rule_elem_dots,
808 mcode ender,
34e49164
C
809 List.map
810 (whencode (statement_dots Ast.Sequencible)
811 (statement Ast.NotSequencible))
812 whn,
813 multi,[],[])
814 | Ast0.Dots(d,whn) ->
815 let d = mcode d in
816 let whn =
817 List.map
818 (whencode (statement_dots Ast.Sequencible)
819 (statement Ast.NotSequencible))
820 whn in
821 Ast.Dots(d,whn,[],[])
822 | Ast0.Circles(d,whn) ->
823 let d = mcode d in
824 let whn =
825 List.map
826 (whencode (statement_dots Ast.Sequencible)
827 (statement Ast.NotSequencible))
828 whn in
829 Ast.Circles(d,whn,[],[])
830 | Ast0.Stars(d,whn) ->
831 let d = mcode d in
832 let whn =
833 List.map
834 (whencode (statement_dots Ast.Sequencible)
835 (statement Ast.NotSequencible))
836 whn in
837 Ast.Stars(d,whn,[],[])
838 | Ast0.FunDecl((_,bef),fi,name,lp,params,rp,lbrace,body,rbrace) ->
839 let fi = List.map fninfo fi in
840 let name = ident name in
841 let lp = mcode lp in
842 let params = parameter_list params in
843 let rp = mcode rp in
844 let lbrace = mcode lbrace in
708f4980 845 let body = dots (statement seqible) body in
34e49164 846 let rbrace = mcode rbrace in
b1b2de81 847 let allminus = check_allminus.VT0.combiner_rec_statement s in
34e49164 848 Ast.FunDecl(rewrap_rule_elem s
708f4980 849 (Ast.FunHeader(convert_mcodekind (-1) bef,
34e49164
C
850 allminus,fi,name,lp,params,rp)),
851 tokenwrap lbrace s (Ast.SeqStart(lbrace)),
708f4980 852 body,
34e49164
C
853 tokenwrap rbrace s (Ast.SeqEnd(rbrace)))
854 | Ast0.Include(inc,str) ->
855 Ast.Atomic(rewrap_rule_elem s (Ast.Include(mcode inc,mcode str)))
3a314143
C
856 | Ast0.Undef(def,id) ->
857 Ast.Atomic(rewrap_rule_elem s (Ast.Undef(mcode def,ident id)))
34e49164
C
858 | Ast0.Define(def,id,params,body) ->
859 Ast.Define
860 (rewrap_rule_elem s
861 (Ast.DefineHeader
862 (mcode def,ident id, define_parameters params)),
863 statement_dots Ast.NotSequencible (*not sure*) body)
864 | Ast0.OptStm(stm) -> Ast.OptStm(statement seqible stm)
865 | Ast0.UniqueStm(stm) -> Ast.UniqueStm(statement seqible stm))
866
867 and define_parameters p =
868 rewrap p no_isos
869 (match Ast0.unwrap p with
870 Ast0.NoParams -> Ast.NoParams
871 | Ast0.DParams(lp,params,rp) ->
872 Ast.DParams(mcode lp,
873 dots define_param params,
874 mcode rp))
875
876 and define_param p =
877 rewrap p no_isos
878 (match Ast0.unwrap p with
879 Ast0.DParam(id) -> Ast.DParam(ident id)
880 | Ast0.DPComma(comma) -> Ast.DPComma(mcode comma)
881 | Ast0.DPdots(d) -> Ast.DPdots(mcode d)
882 | Ast0.DPcircles(c) -> Ast.DPcircles(mcode c)
883 | Ast0.OptDParam(dp) -> Ast.OptDParam(define_param dp)
884 | Ast0.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp))
885
886 and whencode notfn alwaysfn = function
887 Ast0.WhenNot a -> Ast.WhenNot (notfn a)
888 | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a)
889 | Ast0.WhenModifier(x) -> Ast.WhenModifier(x)
1be43e12
C
890 | x ->
891 let rewrap_rule_elem ast0 ast =
892 rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in
893 match x with
894 Ast0.WhenNotTrue(e) ->
895 Ast.WhenNotTrue(rewrap_rule_elem e (Ast.Exp(expression e)))
896 | Ast0.WhenNotFalse(e) ->
897 Ast.WhenNotFalse(rewrap_rule_elem e (Ast.Exp(expression e)))
898 | _ -> failwith "not possible"
34e49164
C
899
900 and process_list seqible isos = function
901 [] -> []
902 | x::rest ->
903 let first = statement seqible x in
904 let first =
905 if !Flag.track_iso_usage
906 then Ast.set_isos first (isos@(Ast.get_isos first))
907 else first in
908 (match Ast0.unwrap x with
909 Ast0.Dots(_,_) | Ast0.Nest(_) ->
910 first::(process_list (Ast.SequencibleAfterDots []) no_isos rest)
911 | _ ->
912 first::(process_list Ast.Sequencible no_isos rest))
913
914 and statement_dots seqible d =
915 let isos = do_isos (Ast0.get_iso d) in
916 rewrap d no_isos
917 (match Ast0.unwrap d with
918 Ast0.DOTS(x) -> Ast.DOTS(process_list seqible isos x)
919 | Ast0.CIRCLES(x) -> Ast.CIRCLES(process_list seqible isos x)
920 | Ast0.STARS(x) -> Ast.STARS(process_list seqible isos x))
921
708f4980
C
922 (* the following is no longer used.
923 the goal was to let one put a statement at the very beginning of a function
924 pattern and have it skip over the declarations in the C code.
925 that feature was removed a long time ago, however, in favor of
926 ... when != S, which also causes whatever comes after it to match the
927 first real statement.
928 the separation of declarations from the rest of the body means that the
929 quantifier of any variable shared between them comes out too high, posing
930 problems when there is ... decl ... stmt, as the quantifier of any shared
931 variable will be around the whole thing, making variables not free enough
932 in the first ..., and thus not implementing the expected shortest path
933 condition. example: f() { ... int A; ... foo(A); }.
934 the quantifier for A should start just before int A, not at the top of the
935 function.
34e49164
C
936 and separate_decls seqible d =
937 let rec collect_decls = function
938 [] -> ([],[])
939 | (x::xs) as l ->
940 (match Ast0.unwrap x with
941 Ast0.Decl(_) ->
942 let (decls,other) = collect_decls xs in
943 (x :: decls,other)
944 | Ast0.Dots(_,_) | Ast0.Nest(_,_,_,_,_) ->
945 let (decls,other) = collect_decls xs in
946 (match decls with
947 [] -> ([],x::other)
948 | _ -> (x :: decls,other))
949 | Ast0.Disj(starter,stmt_dots_list,mids,ender) ->
950 let disjs = List.map collect_dot_decls stmt_dots_list in
951 let all_decls = List.for_all (function (_,s) -> s=[]) disjs in
952 if all_decls
953 then
954 let (decls,other) = collect_decls xs in
955 (x :: decls,other)
956 else ([],l)
957 | _ -> ([],l))
958
959 and collect_dot_decls d =
960 match Ast0.unwrap d with
961 Ast0.DOTS(x) -> collect_decls x
962 | Ast0.CIRCLES(x) -> collect_decls x
963 | Ast0.STARS(x) -> collect_decls x in
964
965 let process l d fn =
966 let (decls,other) = collect_decls l in
967 (rewrap d no_isos (fn (List.map (statement seqible) decls)),
968 rewrap d no_isos
969 (fn (process_list seqible (do_isos (Ast0.get_iso d)) other))) in
970 match Ast0.unwrap d with
971 Ast0.DOTS(x) -> process x d (function x -> Ast.DOTS x)
972 | Ast0.CIRCLES(x) -> process x d (function x -> Ast.CIRCLES x)
708f4980 973 | Ast0.STARS(x) -> process x d (function x -> Ast.STARS x) *) in
34e49164
C
974
975 statement Ast.Sequencible s
976
977and fninfo = function
978 Ast0.FStorage(stg) -> Ast.FStorage(mcode stg)
979 | Ast0.FType(ty) -> Ast.FType(typeC ty)
980 | Ast0.FInline(inline) -> Ast.FInline(mcode inline)
981 | Ast0.FAttr(attr) -> Ast.FAttr(mcode attr)
982
983and option_to_list = function
984 Some x -> [x]
985 | None -> []
986
987and case_line c =
988 rewrap c no_isos
989 (match Ast0.unwrap c with
990 Ast0.Default(def,colon,code) ->
991 let def = mcode def in
992 let colon = mcode colon in
993 let code = dots statement code in
994 Ast.CaseLine(rewrap c no_isos (Ast.Default(def,colon)),code)
995 | Ast0.Case(case,exp,colon,code) ->
996 let case = mcode case in
997 let exp = expression exp in
998 let colon = mcode colon in
999 let code = dots statement code in
1000 Ast.CaseLine(rewrap c no_isos (Ast.Case(case,exp,colon)),code)
fc1ad971
C
1001 | Ast0.DisjCase(_,case_lines,_,_) ->
1002 failwith "not supported"
1003 (*Ast.CaseLine(Ast.DisjRuleElem(List.map case_line case_lines))*)
1004
34e49164
C
1005 | Ast0.OptCase(case) -> Ast.OptCase(case_line case))
1006
1007and statement_dots l = dots statement l
faf9a90c 1008
34e49164
C
1009(* --------------------------------------------------------------------- *)
1010
1011(* what is possible is only what is at the top level in an iso *)
1012and anything = function
1013 Ast0.DotsExprTag(d) -> Ast.ExprDotsTag(expression_dots d)
1014 | Ast0.DotsParamTag(d) -> Ast.ParamDotsTag(parameter_list d)
1015 | Ast0.DotsInitTag(d) -> failwith "not possible"
1016 | Ast0.DotsStmtTag(d) -> Ast.StmtDotsTag(statement_dots d)
1017 | Ast0.DotsDeclTag(d) -> Ast.DeclDotsTag(declaration_dots d)
1018 | Ast0.DotsCaseTag(d) -> failwith "not possible"
1019 | Ast0.IdentTag(d) -> Ast.IdentTag(ident d)
1020 | Ast0.ExprTag(d) -> Ast.ExpressionTag(expression d)
1021 | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
1022 failwith "only in isos, not converted to ast"
1023 | Ast0.TypeCTag(d) -> Ast.FullTypeTag(typeC d)
1024 | Ast0.ParamTag(d) -> Ast.ParamTag(parameterTypeDef d)
1025 | Ast0.InitTag(d) -> Ast.InitTag(initialiser d)
1026 | Ast0.DeclTag(d) -> Ast.DeclarationTag(declaration d)
1027 | Ast0.StmtTag(d) -> Ast.StatementTag(statement d)
1028 | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d)
1029 | Ast0.TopTag(d) -> Ast.Code(top_level d)
1030 | Ast0.IsoWhenTag(_) -> failwith "not possible"
1be43e12
C
1031 | Ast0.IsoWhenTTag(_) -> failwith "not possible"
1032 | Ast0.IsoWhenFTag(_) -> failwith "not possible"
34e49164
C
1033 | Ast0.MetaPosTag _ -> failwith "not possible"
1034
1035(* --------------------------------------------------------------------- *)
1036(* Function declaration *)
1037(* top level isos are probably lost to tracking *)
faf9a90c 1038
34e49164
C
1039and top_level t =
1040 rewrap t no_isos
1041 (match Ast0.unwrap t with
1042 Ast0.FILEINFO(old_file,new_file) ->
1043 Ast.FILEINFO(mcode old_file,mcode new_file)
1044 | Ast0.DECL(stmt) -> Ast.DECL(statement stmt)
1045 | Ast0.CODE(rule_elem_dots) ->
1046 Ast.CODE(statement_dots rule_elem_dots)
1047 | Ast0.ERRORWORDS(exps) -> Ast.ERRORWORDS(List.map expression exps)
1048 | Ast0.OTHER(_) -> failwith "eliminated by top_level")
1049
1050(* --------------------------------------------------------------------- *)
1051(* Entry point for minus code *)
1052
1053(* Inline_mcodes is very important - sends + code attached to the - code
1054down to the mcodes. The functions above can only be used when there is no
1055attached + code, eg in + code itself. *)
1056let ast0toast_toplevel x =
b1b2de81 1057 inline_mcodes.VT0.combiner_rec_top_level x;
34e49164
C
1058 top_level x
1059
faf9a90c 1060let ast0toast name deps dropped exists x is_exp ruletype =
b1b2de81 1061 List.iter inline_mcodes.VT0.combiner_rec_top_level x;
faf9a90c
C
1062 Ast.CocciRule
1063 (name,(deps,dropped,exists),List.map top_level x,is_exp,ruletype)