permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_c / visitor_c.ml
CommitLineData
0708f913 1(* Yoann Padioleau
ae4735db
C
2 *
3 * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
0708f913 4 * Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes
34e49164
C
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License (GPL)
8 * version 2 as published by the Free Software Foundation.
ae4735db 9 *
34e49164
C
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * file license.txt for more details.
14 *)
15open Common
16
17
18open Ast_c
19module F = Control_flow_c
20
91eba41f
C
21(*****************************************************************************)
22(* Prelude *)
23(*****************************************************************************)
24
25(* todo? dont go in Include. Have a visitor flag ? disable_go_include ?
26 * disable_go_type_annotation ?
27 *)
28
708f4980
C
29(*****************************************************************************)
30(* Wrappers *)
31(*****************************************************************************)
32let pr2, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_visit
33
34e49164
C
34(*****************************************************************************)
35(* Functions to visit the Ast, and now also the CFG nodes *)
36(*****************************************************************************)
37
ae4735db
C
38(* Why this module ?
39 *
40 * The problem is that we manipulate the AST of C programs
41 * and some of our analysis need only to specify an action for
113803cf 42 * specific cases, such as the function call case, and recurse
ae4735db
C
43 * for the other cases.
44 * Here is a simplification of our AST:
45 *
46 * type ctype =
113803cf
C
47 * | Basetype of ...
48 * | Pointer of ctype
49 * | Array of expression option * ctype
50 * | ...
ae4735db 51 * and expression =
113803cf
C
52 * | Ident of string
53 * | FunCall of expression * expression list
54 * | Postfix of ...
55 * | RecordAccess of ..
56 * | ...
ae4735db 57 * and statement =
113803cf
C
58 * ...
59 * and declaration =
60 * ...
ae4735db 61 * and program =
113803cf
C
62 * ...
63 *
ae4735db
C
64 * What we want is really write code like
65 *
66 * let my_analysis program =
113803cf
C
67 * analyze_all_expressions program (fun expr ->
68 * match expr with
69 * | FunCall (e, es) -> do_something()
ae4735db 70 * | _ -> <find_a_way_to_recurse_for_all_the_other_cases>
113803cf 71 * )
ae4735db 72 *
113803cf
C
73 * The problem is how to write analyze_all_expressions
74 * and find_a_way_to_recurse_for_all_the_other_cases.
ae4735db
C
75 *
76 * Our solution is to mix the ideas of visitor, pattern matching,
113803cf 77 * and continuation. Here is how it looks like
ae4735db
C
78 * using our hybrid-visitor API:
79 *
80 * let my_analysis program =
113803cf 81 * Visitor.visit_iter program {
ae4735db 82 * Visitor.kexpr = (fun k e ->
113803cf
C
83 * match e with
84 * | FunCall (e, es) -> do_something()
85 * | _ -> k e
86 * );
87 * }
ae4735db
C
88 *
89 * You can of course also give action "hooks" for
113803cf
C
90 * kstatement, ktype, or kdeclaration. But we don't overuse
91 * visitors and so it would be stupid to provide
92 * kfunction_call, kident, kpostfix hooks as one can just
93 * use pattern matching with kexpr to achieve the same effect.
ae4735db 94 *
0708f913
C
95 * Note: when want to apply recursively, always apply the continuator
96 * on the toplevel expression, otherwise may miss some intermediate steps.
97 * Do
98 * match expr with
99 * | FunCall (e, es) -> ...
100 * k expr
101 * Or
102 * match expr with
103 * | FunCall (e, es) -> ...
104 * Visitor_c.vk_expr bigf e
105 * Not
106 * match expr with
107 * | FunCall (e, es) -> ...
108 * k e
109 *
ae4735db
C
110 *
111 *
112 *
113 *
113803cf
C
114 * Alternatives: from the caml mailing list:
115 * "You should have a look at the Camlp4 metaprogramming facilities :
116 * http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator
117 * You would write something like" :
118 * let my_analysis program =
119 * let analysis = object (self)
120 * inherit fold as super
121 * method expr = function
122 * | FunCall (e, es) -> do_something (); self
123 * | other -> super#expr other
124 * end in analysis#expr
ae4735db
C
125 *
126 * The problem is that you don't have control about what is generated
113803cf 127 * and in our case we sometimes dont want to visit too much. For instance
b1b2de81 128 * our visitor don't recurse on the type annotation of expressions
ae4735db 129 * Ok, this could be worked around, but the pb remains, you
113803cf
C
130 * don't have control and at some point you may want. In the same
131 * way we want to enforce a certain order in the visit (ok this is not good,
132 * but it's convenient) of ast elements. For instance first
133 * processing the left part 'e' of a Funcall(e,es), then the arguments 'es'.
ae4735db 134 *
113803cf 135 *)
34e49164 136
ae4735db
C
137(* Visitor based on continuation. Cleaner than the one based on mutable
138 * pointer functions that I had before.
485bce71 139 * src: based on a (vague) idea from Remy Douence.
ae4735db
C
140 *
141 *
142 *
34e49164 143 * Diff with Julia's visitor ? She does:
ae4735db 144 *
34e49164
C
145 * let ident r k i =
146 * ...
147 * let expression r k e =
ae4735db 148 * ...
34e49164
C
149 * ... (List.map r.V0.combiner_expression expr_list) ...
150 * ...
ae4735db 151 * let res = V0.combiner bind option_default
34e49164
C
152 * mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
153 * donothing donothing donothing donothing
154 * ident expression typeC donothing parameter declaration statement
155 * donothing in
156 * ...
157 * collect_unitary_nonunitary
158 * (List.concat (List.map res.V0.combiner_top_level t))
ae4735db
C
159 *
160 *
161 *
34e49164 162 * So she has to remember at which position you must put the 'expression'
ae4735db
C
163 * function. I use record which is easier.
164 *
34e49164 165 * When she calls recursively, her res.V0.combiner_xxx does not take bigf
ae4735db
C
166 * in param whereas I do
167 * | F.Decl decl -> Visitor_c.vk_decl bigf decl
34e49164
C
168 * And with the record she gets, she does not have to do my
169 * multiple defs of function such as 'let al_type = V0.vk_type_s bigf'
ae4735db 170 *
34e49164
C
171 * The code of visitor.ml is cleaner with julia because mutual recursive calls
172 * are clean such as ... 'expression e' ... and not 'f (k, bigf) e'
173 * or 'vk_expr bigf e'.
ae4735db 174 *
34e49164
C
175 * So it is very dual:
176 * - I give a record but then I must handle bigf.
177 * - She gets a record, and gives a list of function
ae4735db
C
178 *
179 *)
180
34e49164 181
ae4735db 182(* old: first version (only visiting expr)
34e49164
C
183
184let (iter_expr:((expression -> unit) -> expression -> unit) -> expression -> unit)
185 = fun f expr ->
ae4735db 186 let rec k e =
34e49164
C
187 match e with
188 | Constant c -> ()
189 | FunCall (e, es) -> f k e; List.iter (f k) es
190 | CondExpr (e1, e2, e3) -> f k e1; f k e2; f k e3
191 | Sequence (e1, e2) -> f k e1; f k e2;
192 | Assignment (e1, op, e2) -> f k e1; f k e2;
ae4735db 193
34e49164
C
194 | Postfix (e, op) -> f k e
195 | Infix (e, op) -> f k e
196 | Unary (e, op) -> f k e
197 | Binary (e1, op, e2) -> f k e1; f k e2;
ae4735db 198
34e49164
C
199 | ArrayAccess (e1, e2) -> f k e1; f k e2;
200 | RecordAccess (e, s) -> f k e
201 | RecordPtAccess (e, s) -> f k e
202
203 | SizeOfExpr e -> f k e
204 | SizeOfType t -> ()
205 | _ -> failwith "to complete"
206
207 in f k expr
208
ae4735db 209let ex1 = Sequence (Sequence (Constant (Ident "1"), Constant (Ident "2")),
34e49164 210 Constant (Ident "4"))
ae4735db 211let test =
34e49164
C
212 iter_expr (fun k e -> match e with
213 | Constant (Ident x) -> Common.pr2 x
214 | rest -> k rest
ae4735db
C
215 ) ex1
216==>
34e49164
C
2171
2182
2194
220
221*)
222
223(*****************************************************************************)
224(* Side effect style visitor *)
225(*****************************************************************************)
226
227(* Visitors for all langage concept, not just for expression.
ae4735db 228 *
34e49164
C
229 * Note that I don't visit necesserally in the order of the token
230 * found in the original file. So don't assume such hypothesis!
ae4735db 231 *
951c7801 232 * todo? parameter ?
34e49164 233 *)
ae4735db
C
234type visitor_c =
235 {
34e49164
C
236 kexpr: (expression -> unit) * visitor_c -> expression -> unit;
237 kstatement: (statement -> unit) * visitor_c -> statement -> unit;
238 ktype: (fullType -> unit) * visitor_c -> fullType -> unit;
239
240 kdecl: (declaration -> unit) * visitor_c -> declaration -> unit;
951c7801
C
241 konedecl: (onedecl -> unit) * visitor_c -> onedecl -> unit;
242 kparam: (parameterType -> unit) * visitor_c -> parameterType -> unit;
ae4735db 243 kdef: (definition -> unit) * visitor_c -> definition -> unit;
b1b2de81
C
244 kname : (name -> unit) * visitor_c -> name -> unit;
245
ae4735db 246 kini: (initialiser -> unit) * visitor_c -> initialiser -> unit;
b1b2de81 247 kfield: (field -> unit) * visitor_c -> field -> unit;
34e49164 248
485bce71
C
249 kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
250 kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
251 kstatementseq: (statement_sequencable -> unit) * visitor_c -> statement_sequencable -> unit;
34e49164 252
0708f913 253
34e49164
C
254 (* CFG *)
255 knode: (F.node -> unit) * visitor_c -> F.node -> unit;
256 (* AST *)
257 ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
485bce71
C
258
259 kinfo: (info -> unit) * visitor_c -> info -> unit;
ae4735db 260 }
34e49164 261
ae4735db 262let default_visitor_c =
b1b2de81
C
263 { kexpr = (fun (k,_) e -> k e);
264 kstatement = (fun (k,_) st -> k st);
265 ktype = (fun (k,_) t -> k t);
266 kdecl = (fun (k,_) d -> k d);
951c7801
C
267 konedecl = (fun (k,_) d -> k d);
268 kparam = (fun (k,_) d -> k d);
b1b2de81
C
269 kdef = (fun (k,_) d -> k d);
270 kini = (fun (k,_) ie -> k ie);
271 kname = (fun (k,_) x -> k x);
272 kinfo = (fun (k,_) ii -> k ii);
273 knode = (fun (k,_) n -> k n);
274 ktoplevel = (fun (k,_) p -> k p);
485bce71 275 kcppdirective = (fun (k,_) p -> k p);
b1b2de81
C
276 kdefineval = (fun (k,_) p -> k p);
277 kstatementseq = (fun (k,_) p -> k p);
278 kfield = (fun (k,_) p -> k p);
ae4735db 279 }
34e49164 280
485bce71
C
281
282(* ------------------------------------------------------------------------ *)
283
284
34e49164
C
285let rec vk_expr = fun bigf expr ->
286 let iif ii = vk_ii bigf ii in
287
288 let rec exprf e = bigf.kexpr (k,bigf) e
91eba41f 289 (* !!! dont go in _typ !!! *)
ae4735db 290 and k ((e,_typ), ii) =
34e49164
C
291 iif ii;
292 match e with
b1b2de81 293 | Ident (name) -> vk_name bigf name
34e49164 294 | Constant (c) -> ()
ae4735db
C
295 | FunCall (e, es) ->
296 exprf e;
485bce71 297 vk_argument_list bigf es;
ae4735db 298 | CondExpr (e1, e2, e3) ->
34e49164
C
299 exprf e1; do_option (exprf) e2; exprf e3
300 | Sequence (e1, e2) -> exprf e1; exprf e2;
301 | Assignment (e1, op, e2) -> exprf e1; exprf e2;
ae4735db 302
34e49164
C
303 | Postfix (e, op) -> exprf e
304 | Infix (e, op) -> exprf e
305 | Unary (e, op) -> exprf e
306 | Binary (e1, op, e2) -> exprf e1; exprf e2;
ae4735db 307
34e49164 308 | ArrayAccess (e1, e2) -> exprf e1; exprf e2;
b1b2de81
C
309 | RecordAccess (e, name) -> exprf e; vk_name bigf name
310 | RecordPtAccess (e, name) -> exprf e; vk_name bigf name
34e49164
C
311
312 | SizeOfExpr (e) -> exprf e
313 | SizeOfType (t) -> vk_type bigf t
314 | Cast (t, e) -> vk_type bigf t; exprf e
315
ae4735db
C
316 (* old: | StatementExpr (((declxs, statxs), is)), is2 ->
317 * List.iter (vk_decl bigf) declxs;
318 * List.iter (vk_statement bigf) statxs
34e49164 319 *)
ae4735db 320 | StatementExpr ((statxs, is)) ->
34e49164 321 iif is;
485bce71 322 statxs +> List.iter (vk_statement_sequencable bigf);
34e49164 323
7fe62b65
C
324 | Constructor (t, init) ->
325 vk_type bigf t; vk_ini bigf init
ae4735db 326
34e49164
C
327 | ParenExpr (e) -> exprf e
328
1b9ae606
C
329 | New (None, t) -> vk_argument bigf t
330 | New (Some ts, t) ->
331 vk_argument_list bigf ts;
332 vk_argument bigf t
4dfbc1c2 333 | Delete e -> vk_expr bigf e
f59c9fb7 334
34e49164
C
335
336 in exprf expr
337
34e49164 338
b1b2de81 339(* ------------------------------------------------------------------------ *)
ae4735db 340and vk_name = fun bigf ident ->
b1b2de81 341 let iif ii = vk_ii bigf ii in
34e49164 342
ae4735db
C
343 let rec namef x = bigf.kname (k,bigf) x
344 and k id =
b1b2de81
C
345 match id with
346 | RegularName (s, ii) -> iif ii
ae4735db
C
347 | CppConcatenatedName xs ->
348 xs +> List.iter (fun ((x,ii1), ii2) ->
b1b2de81
C
349 iif ii2;
350 iif ii1;
351 );
352 | CppVariadicName (s, ii) -> iif ii
ae4735db 353 | CppIdentBuilder ((s,iis), xs) ->
b1b2de81 354 iif iis;
ae4735db 355 xs +> List.iter (fun ((x,iix), iicomma) ->
b1b2de81
C
356 iif iicomma;
357 iif iix;
358 )
359 in
360 namef ident
361
362(* ------------------------------------------------------------------------ *)
34e49164
C
363
364
ae4735db 365and vk_statement = fun bigf (st: Ast_c.statement) ->
34e49164
C
366 let iif ii = vk_ii bigf ii in
367
ae4735db
C
368 let rec statf x = bigf.kstatement (k,bigf) x
369 and k st =
34e49164
C
370 let (unwrap_st, ii) = st in
371 iif ii;
372 match unwrap_st with
ae4735db 373 | Labeled (Label (name, st)) ->
708f4980
C
374 vk_name bigf name;
375 statf st;
34e49164 376 | Labeled (Case (e, st)) -> vk_expr bigf e; statf st;
ae4735db 377 | Labeled (CaseRange (e, e2, st)) ->
34e49164
C
378 vk_expr bigf e; vk_expr bigf e2; statf st;
379 | Labeled (Default st) -> statf st;
380
ae4735db 381 | Compound statxs ->
485bce71 382 statxs +> List.iter (vk_statement_sequencable bigf)
34e49164
C
383 | ExprStatement (eopt) -> do_option (vk_expr bigf) eopt;
384
ae4735db 385 | Selection (If (e, st1, st2)) ->
34e49164 386 vk_expr bigf e; statf st1; statf st2;
ae4735db 387 | Selection (Switch (e, st)) ->
34e49164 388 vk_expr bigf e; statf st;
ae4735db 389 | Iteration (While (e, st)) ->
34e49164 390 vk_expr bigf e; statf st;
ae4735db 391 | Iteration (DoWhile (st, e)) -> statf st; vk_expr bigf e;
755320b0
C
392 | Iteration (For (first, (e2opt,i2), (e3opt,i3), st)) ->
393 (match first with
394 ForExp (e1opt,i1) -> statf (mk_st (ExprStatement (e1opt)) i1)
395 | ForDecl decl -> vk_decl bigf decl);
ae4735db
C
396 statf (mk_st (ExprStatement (e2opt)) i2);
397 statf (mk_st (ExprStatement (e3opt)) i3);
34e49164
C
398 statf st;
399
ae4735db 400 | Iteration (MacroIteration (s, es, st)) ->
485bce71 401 vk_argument_list bigf es;
34e49164 402 statf st;
ae4735db 403
b1b2de81 404 | Jump (Goto name) -> vk_name bigf name
34e49164
C
405 | Jump ((Continue|Break|Return)) -> ()
406 | Jump (ReturnExpr e) -> vk_expr bigf e;
407 | Jump (GotoComputed e) -> vk_expr bigf e;
408
ae4735db 409 | Decl decl -> vk_decl bigf decl
34e49164
C
410 | Asm asmbody -> vk_asmbody bigf asmbody
411 | NestedFunc def -> vk_def bigf def
412 | MacroStmt -> ()
413
414 in statf st
415
ae4735db
C
416and vk_statement_sequencable = fun bigf stseq ->
417 let f = bigf.kstatementseq in
485bce71 418
ae4735db 419 let rec k stseq =
485bce71
C
420 match stseq with
421 | StmtElem st -> vk_statement bigf st
ae4735db 422 | CppDirectiveStmt directive ->
485bce71 423 vk_cpp_directive bigf directive
ae4735db 424 | IfdefStmt ifdef ->
485bce71 425 vk_ifdef_directive bigf ifdef
ae4735db 426 | IfdefStmt2 (ifdef, xxs) ->
485bce71 427 ifdef +> List.iter (vk_ifdef_directive bigf);
ae4735db 428 xxs +> List.iter (fun xs ->
485bce71
C
429 xs +> List.iter (vk_statement_sequencable bigf)
430 )
ae4735db 431
485bce71
C
432 in f (k, bigf) stseq
433
34e49164 434
34e49164 435
ae4735db 436and vk_type = fun bigf t ->
34e49164
C
437 let iif ii = vk_ii bigf ii in
438
ae4735db
C
439 let rec typef x = bigf.ktype (k, bigf) x
440 and k t =
34e49164
C
441 let (q, t) = t in
442 let (unwrap_q, iiq) = q in
443 let (unwrap_t, iit) = t in
444 iif iiq;
445 iif iit;
446 match unwrap_t with
190f1acf 447 | NoType -> ()
34e49164
C
448 | BaseType _ -> ()
449 | Pointer t -> typef t
ae4735db 450 | Array (eopt, t) ->
34e49164 451 do_option (vk_expr bigf) eopt;
ae4735db
C
452 typef t
453 | FunctionType (returnt, paramst) ->
34e49164
C
454 typef returnt;
455 (match paramst with
ae4735db 456 | (ts, (b,iihas3dots)) ->
34e49164 457 iif iihas3dots;
485bce71 458 vk_param_list bigf ts
34e49164
C
459 )
460
ae4735db 461 | Enum (sopt, enumt) ->
c491d8ee 462 vk_enum_fields bigf enumt
ae4735db
C
463
464 | StructUnion (sopt, _su, fields) ->
34e49164
C
465 vk_struct_fields bigf fields
466
467 | StructUnionName (s, structunion) -> ()
468 | EnumName s -> ()
469
470 (* dont go in _typ *)
ae4735db 471 | TypeName (name,_typ) ->
b1b2de81 472 vk_name bigf name
34e49164
C
473
474 | ParenType t -> typef t
475 | TypeOfExpr e -> vk_expr bigf e
476 | TypeOfType t -> typef t
477
478 in typef t
479
485bce71 480
ae4735db 481and vk_attribute = fun bigf attr ->
485bce71
C
482 let iif ii = vk_ii bigf ii in
483 match attr with
ae4735db 484 | Attribute s, ii ->
485bce71
C
485 iif ii
486
487
488(* ------------------------------------------------------------------------ *)
489
ae4735db 490and vk_decl = fun bigf d ->
34e49164
C
491 let iif ii = vk_ii bigf ii in
492
ae4735db
C
493 let f = bigf.kdecl in
494 let rec k decl =
495 match decl with
785a3008
C
496 | DeclList (xs,ii) ->
497 iif ii;
498 xs +> List.iter (fun (x,ii) ->
91eba41f 499 iif ii;
17ba0788 500 vk_onedecl bigf x
91eba41f 501 );
5427db06 502 | MacroDecl ((s, args, ptvg),ii) ->
17ba0788
C
503 iif ii;
504 vk_argument_list bigf args
505 | MacroDeclInit ((s, args, ini),ii) ->
34e49164 506 iif ii;
485bce71 507 vk_argument_list bigf args;
17ba0788 508 vk_ini bigf ini
ae4735db 509 in f (k, bigf) d
91eba41f 510
190f1acf
C
511and vk_decl_list = fun bigf ts ->
512 ts +> List.iter (vk_decl bigf)
91eba41f 513
ae4735db 514and vk_onedecl = fun bigf onedecl ->
91eba41f 515 let iif ii = vk_ii bigf ii in
ae4735db
C
516 let f = bigf.konedecl in
517 let rec k onedecl =
91eba41f 518 match onedecl with
ae4735db
C
519 | ({v_namei = var;
520 v_type = t;
978fd7e5 521 v_type_bis = tbis;
ae4735db
C
522 v_storage = _sto;
523 v_attr = attrs}) ->
34e49164 524
34e49164 525 vk_type bigf t;
978fd7e5 526 (* dont go in tbis *)
485bce71 527 attrs +> List.iter (vk_attribute bigf);
ae4735db 528 var +> Common.do_option (fun (name, iniopt) ->
b1b2de81 529 vk_name bigf name;
4dfbc1c2
C
530 (match iniopt with
531 Ast_c.NoInit -> ()
532 | Ast_c.ValInit(iini,init) -> iif [iini]; vk_ini bigf init
533 | Ast_c.ConstrInit((init,ii)) -> iif ii; vk_argument_list bigf init)
b1b2de81 534 )
951c7801 535 in f (k, bigf) onedecl
34e49164 536
ae4735db 537and vk_ini = fun bigf ini ->
34e49164
C
538 let iif ii = vk_ii bigf ii in
539
ae4735db
C
540 let rec inif x = bigf.kini (k, bigf) x
541 and k (ini, iini) =
34e49164
C
542 iif iini;
543 match ini with
544 | InitExpr e -> vk_expr bigf e
ae4735db
C
545 | InitList initxs ->
546 initxs +> List.iter (fun (ini, ii) ->
34e49164
C
547 inif ini;
548 iif ii;
ae4735db
C
549 )
550 | InitDesignators (xs, e) ->
34e49164
C
551 xs +> List.iter (vk_designator bigf);
552 inif e
553
554 | InitFieldOld (s, e) -> inif e
555 | InitIndexOld (e1, e) ->
556 vk_expr bigf e1; inif e
557
485bce71 558
34e49164
C
559 in inif ini
560
8f657093
C
561and vk_ini_list = fun bigf ts ->
562 let iif ii = vk_ii bigf ii in
563 ts +> List.iter (fun (ini,iicomma) ->
564 vk_ini bigf ini;
565 iif iicomma;
566 )
34e49164 567
ae4735db 568and vk_designator = fun bigf design ->
34e49164
C
569 let iif ii = vk_ii bigf ii in
570 let (designator, ii) = design in
571 iif ii;
572 match designator with
573 | DesignatorField s -> ()
574 | DesignatorIndex e -> vk_expr bigf e
575 | DesignatorRange (e1, e2) -> vk_expr bigf e1; vk_expr bigf e2
576
485bce71
C
577
578(* ------------------------------------------------------------------------ *)
579
ae4735db 580and vk_struct_fields = fun bigf fields ->
0708f913
C
581 fields +> List.iter (vk_struct_field bigf);
582
ae4735db 583and vk_struct_field = fun bigf field ->
34e49164
C
584 let iif ii = vk_ii bigf ii in
585
0708f913 586 let f = bigf.kfield in
ae4735db 587 let rec k field =
0708f913 588
ae4735db
C
589 match field with
590 | DeclarationField
591 (FieldDeclList (onefield_multivars, iiptvirg)) ->
485bce71
C
592 vk_struct_fieldkinds bigf onefield_multivars;
593 iif iiptvirg;
708f4980 594 | EmptyField info -> iif [info]
ae4735db 595 | MacroDeclField ((s, args),ii) ->
708f4980
C
596 iif ii;
597 vk_argument_list bigf args;
485bce71 598
ae4735db 599 | CppDirectiveStruct directive ->
485bce71 600 vk_cpp_directive bigf directive
ae4735db 601 | IfdefStruct ifdef ->
485bce71 602 vk_ifdef_directive bigf ifdef
0708f913
C
603 in
604 f (k, bigf) field
485bce71 605
34e49164 606
ae4735db
C
607
608
609and vk_struct_fieldkinds = fun bigf onefield_multivars ->
34e49164
C
610 let iif ii = vk_ii bigf ii in
611 onefield_multivars +> List.iter (fun (field, iicomma) ->
612 iif iicomma;
613 match field with
ae4735db 614 | Simple (nameopt, t) ->
b1b2de81
C
615 Common.do_option (vk_name bigf) nameopt;
616 vk_type bigf t;
ae4735db 617 | BitField (nameopt, t, info, expr) ->
b1b2de81
C
618 Common.do_option (vk_name bigf) nameopt;
619 vk_info bigf info;
34e49164 620 vk_expr bigf expr;
ae4735db 621 vk_type bigf t
34e49164
C
622 )
623
c491d8ee
C
624
625and vk_enum_fields = fun bigf enumt ->
626 let iif ii = vk_ii bigf ii in
627 enumt +> List.iter (fun ((name, eopt), iicomma) ->
628 vk_oneEnum bigf (name, eopt);
629 iif iicomma)
630
631and vk_oneEnum = fun bigf (name, eopt) ->
632 let iif ii = vk_ii bigf ii in
633 vk_name bigf name;
634 eopt +> Common.do_option (fun (info, e) ->
635 iif [info];
636 vk_expr bigf e
637 )
638
485bce71 639(* ------------------------------------------------------------------------ *)
34e49164
C
640
641
ae4735db 642and vk_def = fun bigf d ->
34e49164
C
643 let iif ii = vk_ii bigf ii in
644
645 let f = bigf.kdef in
ae4735db 646 let rec k d =
34e49164 647 match d with
708f4980 648 | {f_name = name;
485bce71
C
649 f_type = (returnt, (paramst, (b, iib)));
650 f_storage = sto;
651 f_body = statxs;
652 f_attr = attrs;
91eba41f 653 f_old_c_style = oldstyle;
ae4735db
C
654 }, ii
655 ->
34e49164
C
656 iif ii;
657 iif iib;
485bce71 658 attrs +> List.iter (vk_attribute bigf);
34e49164 659 vk_type bigf returnt;
708f4980 660 vk_name bigf name;
ae4735db 661 paramst +> List.iter (fun (param,iicomma) ->
34e49164
C
662 vk_param bigf param;
663 iif iicomma;
664 );
ae4735db 665 oldstyle +> Common.do_option (fun decls ->
91eba41f
C
666 decls +> List.iter (vk_decl bigf);
667 );
668
485bce71 669 statxs +> List.iter (vk_statement_sequencable bigf)
ae4735db 670 in f (k, bigf) d
34e49164
C
671
672
673
674
ae4735db 675and vk_toplevel = fun bigf p ->
34e49164
C
676 let f = bigf.ktoplevel in
677 let iif ii = vk_ii bigf ii in
ae4735db 678 let rec k p =
34e49164
C
679 match p with
680 | Declaration decl -> (vk_decl bigf decl)
681 | Definition def -> (vk_def bigf def)
682 | EmptyDef ii -> iif ii
ae4735db 683 | MacroTop (s, xs, ii) ->
485bce71
C
684 vk_argument_list bigf xs;
685 iif ii
686
687 | CppTop top -> vk_cpp_directive bigf top
688 | IfdefTop ifdefdir -> vk_ifdef_directive bigf ifdefdir
ae4735db 689
485bce71
C
690 | NotParsedCorrectly ii -> iif ii
691 | FinalDef info -> vk_info bigf info
1b9ae606
C
692
693 | Namespace (tls, ii) -> List.iter (vk_toplevel bigf) tls
485bce71
C
694 in f (k, bigf) p
695
ae4735db 696and vk_program = fun bigf xs ->
485bce71
C
697 xs +> List.iter (vk_toplevel bigf)
698
ae4735db 699and vk_ifdef_directive bigf directive =
485bce71
C
700 let iif ii = vk_ii bigf ii in
701 match directive with
702 | IfdefDirective (ifkind, ii) -> iif ii
703
704
705and vk_cpp_directive bigf directive =
706 let iif ii = vk_ii bigf ii in
707 let f = bigf.kcppdirective in
ae4735db 708 let rec k directive =
485bce71
C
709 match directive with
710 | Include {i_include = (s, ii);
711 i_content = copt;
712 }
ae4735db 713 ->
91eba41f
C
714 (* go inside ? yes, can be useful, for instance for type_annotater.
715 * The only pb may be that when we want to unparse the code we
ae4735db 716 * don't want to unparse the included file but the unparser
91eba41f
C
717 * and pretty_print do not use visitor_c so no problem.
718 *)
485bce71 719 iif ii;
ae4735db 720 copt +> Common.do_option (fun (file, asts) ->
485bce71
C
721 vk_program bigf asts
722 );
ae4735db 723 | Define ((s,ii), (defkind, defval)) ->
34e49164
C
724 iif ii;
725 vk_define_kind bigf defkind;
726 vk_define_val bigf defval
ae4735db 727 | PragmaAndCo (ii) ->
485bce71
C
728 iif ii
729 in f (k, bigf) directive
34e49164 730
34e49164 731
ae4735db 732and vk_define_kind bigf defkind =
34e49164
C
733 match defkind with
734 | DefineVar -> ()
ae4735db 735 | DefineFunc (params, ii) ->
34e49164 736 vk_ii bigf ii;
ae4735db 737 params +> List.iter (fun ((s,iis), iicomma) ->
34e49164
C
738 vk_ii bigf iis;
739 vk_ii bigf iicomma;
740 )
3a314143 741 | Undef -> ()
34e49164 742
ae4735db
C
743and vk_define_val bigf defval =
744 let f = bigf.kdefineval in
485bce71 745
ae4735db 746 let rec k defval =
34e49164 747 match defval with
ae4735db 748 | DefineExpr e ->
34e49164
C
749 vk_expr bigf e
750 | DefineStmt stmt -> vk_statement bigf stmt
ae4735db 751 | DefineDoWhileZero ((stmt, e), ii) ->
34e49164 752 vk_statement bigf stmt;
485bce71 753 vk_expr bigf e;
34e49164
C
754 vk_ii bigf ii
755 | DefineFunction def -> vk_def bigf def
756 | DefineType ty -> vk_type bigf ty
757 | DefineText (s, ii) -> vk_ii bigf ii
758 | DefineEmpty -> ()
485bce71 759 | DefineInit ini -> vk_ini bigf ini
abad11c5
C
760 (* christia: added multi *)
761 | DefineMulti stmts ->
762 List.fold_left (fun () d -> vk_statement bigf d) () stmts
ae4735db 763 | DefineTodo ->
91eba41f 764 pr2_once "DefineTodo";
485bce71
C
765 ()
766 in f (k, bigf) defval
34e49164 767
ae4735db
C
768
769
34e49164
C
770
771(* ------------------------------------------------------------------------ *)
ae4735db 772(* Now keep fullstatement inside the control flow node,
34e49164 773 * so that can then get in a MetaStmtVar the fullstatement to later
ae4735db 774 * pp back when the S is in a +. But that means that
34e49164
C
775 * Exp will match an Ifnode even if there is no such exp
776 * inside the condition of the Ifnode (because the exp may
777 * be deeper, in the then branch). So have to not visit
778 * all inside a node anymore.
ae4735db 779 *
485bce71 780 * update: j'ai choisi d'accrocher au noeud du CFG a la
ae4735db 781 * fois le fullstatement et le partialstatement et appeler le
34e49164
C
782 * visiteur que sur le partialstatement.
783 *)
784
ae4735db 785and vk_node = fun bigf node ->
34e49164
C
786 let iif ii = vk_ii bigf ii in
787 let infof info = vk_info bigf info in
788
789 let f = bigf.knode in
ae4735db 790 let rec k n =
34e49164
C
791 match F.unwrap n with
792
91eba41f
C
793 | F.FunHeader (def) ->
794 assert(null (fst def).f_body);
795 vk_def bigf def;
34e49164 796
ae4735db
C
797 | F.Decl decl -> vk_decl bigf decl
798 | F.ExprStatement (st, (eopt, ii)) ->
34e49164
C
799 iif ii;
800 eopt +> do_option (vk_expr bigf)
801
ae4735db 802 | F.IfHeader (_, (e,ii))
34e49164
C
803 | F.SwitchHeader (_, (e,ii))
804 | F.WhileHeader (_, (e,ii))
ae4735db 805 | F.DoWhileTail (e,ii) ->
34e49164
C
806 iif ii;
807 vk_expr bigf e
808
755320b0 809 | F.ForHeader (_st, ((ForExp (e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) ->
34e49164
C
810 iif i1; iif i2; iif i3;
811 iif ii;
812 e1opt +> do_option (vk_expr bigf);
813 e2opt +> do_option (vk_expr bigf);
814 e3opt +> do_option (vk_expr bigf);
755320b0
C
815 | F.ForHeader (_st, ((ForDecl decl, (e2opt,i2), (e3opt,i3)), ii)) ->
816 iif i2; iif i3;
817 iif ii;
818 decl +> (vk_decl bigf);
819 e2opt +> do_option (vk_expr bigf);
820 e3opt +> do_option (vk_expr bigf);
ae4735db 821 | F.MacroIterHeader (_s, ((s,es), ii)) ->
34e49164 822 iif ii;
485bce71 823 vk_argument_list bigf es;
ae4735db 824
34e49164 825 | F.ReturnExpr (_st, (e,ii)) -> iif ii; vk_expr bigf e
ae4735db 826
34e49164 827 | F.Case (_st, (e,ii)) -> iif ii; vk_expr bigf e
ae4735db 828 | F.CaseRange (_st, ((e1, e2),ii)) ->
34e49164
C
829 iif ii; vk_expr bigf e1; vk_expr bigf e2
830
831
832 | F.CaseNode i -> ()
833
834 | F.DefineExpr e -> vk_expr bigf e
835 | F.DefineType ft -> vk_type bigf ft
ae4735db 836 | F.DefineHeader ((s,ii), (defkind)) ->
34e49164
C
837 iif ii;
838 vk_define_kind bigf defkind;
839
840 | F.DefineDoWhileZeroHeader (((),ii)) -> iif ii
ae4735db 841 | F.DefineTodo ->
91eba41f 842 pr2_once "DefineTodo";
485bce71
C
843 ()
844
485bce71 845 | F.Include {i_include = (s, ii);} -> iif ii;
34e49164 846
ae4735db 847 | F.MacroTop (s, args, ii) ->
34e49164 848 iif ii;
485bce71 849 vk_argument_list bigf args
34e49164 850
ae4735db
C
851 | F.IfdefHeader (info) -> vk_ifdef_directive bigf info
852 | F.IfdefElse (info) -> vk_ifdef_directive bigf info
853 | F.IfdefEndif (info) -> vk_ifdef_directive bigf info
34e49164
C
854
855 | F.Break (st,((),ii)) -> iif ii
856 | F.Continue (st,((),ii)) -> iif ii
857 | F.Default (st,((),ii)) -> iif ii
858 | F.Return (st,((),ii)) -> iif ii
b1b2de81
C
859 | F.Goto (st, name, ((),ii)) -> vk_name bigf name; iif ii
860 | F.Label (st, name, ((),ii)) -> vk_name bigf name; iif ii
485bce71 861
34e49164 862 | F.DoHeader (st, info) -> infof info
485bce71 863
34e49164 864 | F.Else info -> infof info
485bce71
C
865 | F.EndStatement iopt -> do_option infof iopt
866
34e49164
C
867 | F.SeqEnd (i, info) -> infof info
868 | F.SeqStart (st, i, info) -> infof info
869
870 | F.MacroStmt (st, ((),ii)) -> iif ii
ae4735db 871 | F.Asm (st, (asmbody,ii)) ->
34e49164
C
872 iif ii;
873 vk_asmbody bigf asmbody
874
875 | (
876 F.TopNode|F.EndNode|
951c7801
C
877 F.ErrorExit|F.Exit|F.Enter|F.LoopFallThroughNode|F.FallThroughNode|
878 F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
34e49164
C
879 F.Fake
880 ) -> ()
881
882
883
884 in
885 f (k, bigf) node
886
887(* ------------------------------------------------------------------------ *)
ae4735db 888and vk_info = fun bigf info ->
34e49164
C
889 let rec infof ii = bigf.kinfo (k, bigf) ii
890 and k i = ()
891 in
892 infof info
893
ae4735db 894and vk_ii = fun bigf ii ->
34e49164
C
895 List.iter (vk_info bigf) ii
896
897
485bce71 898(* ------------------------------------------------------------------------ *)
ae4735db
C
899and vk_argument = fun bigf arg ->
900 let rec do_action = function
485bce71
C
901 | (ActMisc ii) -> vk_ii bigf ii
902 in
903 match arg with
904 | Left e -> (vk_expr bigf) e
905 | Right (ArgType param) -> vk_param bigf param
906 | Right (ArgAction action) -> do_action action
907
ae4735db 908and vk_argument_list = fun bigf es ->
485bce71 909 let iif ii = vk_ii bigf ii in
ae4735db 910 es +> List.iter (fun (e, ii) ->
485bce71
C
911 iif ii;
912 vk_argument bigf e
913 )
914
915
916
b1b2de81 917and vk_param = fun bigf param ->
34e49164 918 let iif ii = vk_ii bigf ii in
ae4735db 919 let f = bigf.kparam in
951c7801
C
920 let rec k param =
921 let {p_namei = swrapopt; p_register = (b, iib); p_type=ft} = param in
922 swrapopt +> Common.do_option (vk_name bigf);
923 iif iib;
924 vk_type bigf ft
925 in f (k, bigf) param
34e49164 926
ae4735db 927and vk_param_list = fun bigf ts ->
485bce71 928 let iif ii = vk_ii bigf ii in
ae4735db 929 ts +> List.iter (fun (param,iicomma) ->
485bce71
C
930 vk_param bigf param;
931 iif iicomma;
932 )
933
934
935
936(* ------------------------------------------------------------------------ *)
ae4735db 937and vk_asmbody = fun bigf (string_list, colon_list) ->
485bce71
C
938 let iif ii = vk_ii bigf ii in
939
940 iif string_list;
ae4735db 941 colon_list +> List.iter (fun (Colon xs, ii) ->
485bce71 942 iif ii;
ae4735db 943 xs +> List.iter (fun (x,iicomma) ->
485bce71
C
944 iif iicomma;
945 (match x with
ae4735db
C
946 | ColonMisc, ii -> iif ii
947 | ColonExpr e, ii ->
485bce71
C
948 vk_expr bigf e;
949 iif ii
950 )
951 ))
952
34e49164 953
485bce71 954(* ------------------------------------------------------------------------ *)
c491d8ee 955let vk_splitted element = fun bigf args_splitted ->
34e49164 956 let iif ii = vk_ii bigf ii in
ae4735db 957 args_splitted +> List.iter (function
c491d8ee 958 | Left arg -> element bigf arg
34e49164
C
959 | Right ii -> iif ii
960 )
961
c491d8ee
C
962let vk_args_splitted = vk_splitted vk_argument
963let vk_define_params_splitted = vk_splitted (fun bigf (_,ii) -> vk_ii bigf ii)
964let vk_params_splitted = vk_splitted vk_param
965let vk_enum_fields_splitted = vk_splitted vk_oneEnum
966let vk_inis_splitted = vk_splitted vk_ini
34e49164 967
485bce71 968(* ------------------------------------------------------------------------ *)
ae4735db 969let vk_cst = fun bigf (cst, ii) ->
34e49164
C
970 let iif ii = vk_ii bigf ii in
971 iif ii;
972 (match cst with
973 | Left cst -> ()
974 | Right s -> ()
975 )
976
977
ae4735db 978
34e49164
C
979
980(*****************************************************************************)
981(* "syntetisized attributes" style *)
982(*****************************************************************************)
485bce71
C
983
984(* TODO port the xxs_s to new cpp construct too *)
985
ae4735db 986type 'a inout = 'a -> 'a
34e49164 987
ae4735db 988(* _s for synthetizized attributes
34e49164
C
989 *
990 * Note that I don't visit necesserally in the order of the token
991 * found in the original file. So don't assume such hypothesis!
992 *)
ae4735db 993type visitor_c_s = {
34e49164
C
994 kexpr_s: (expression inout * visitor_c_s) -> expression inout;
995 kstatement_s: (statement inout * visitor_c_s) -> statement inout;
996 ktype_s: (fullType inout * visitor_c_s) -> fullType inout;
34e49164
C
997
998 kdecl_s: (declaration inout * visitor_c_s) -> declaration inout;
ae4735db 999 kdef_s: (definition inout * visitor_c_s) -> definition inout;
b1b2de81 1000 kname_s: (name inout * visitor_c_s) -> name inout;
34e49164 1001
ae4735db 1002 kini_s: (initialiser inout * visitor_c_s) -> initialiser inout;
34e49164 1003
485bce71 1004 kcppdirective_s: (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
34e49164 1005 kdefineval_s: (define_val inout * visitor_c_s) -> define_val inout;
485bce71
C
1006 kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
1007 kstatementseq_list_s: (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
1008
1009 knode_s: (F.node inout * visitor_c_s) -> F.node inout;
34e49164 1010
485bce71
C
1011
1012 ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
34e49164 1013 kinfo_s: (info inout * visitor_c_s) -> info inout;
ae4735db 1014 }
34e49164 1015
ae4735db 1016let default_visitor_c_s =
34e49164
C
1017 { kexpr_s = (fun (k,_) e -> k e);
1018 kstatement_s = (fun (k,_) st -> k st);
1019 ktype_s = (fun (k,_) t -> k t);
1020 kdecl_s = (fun (k,_) d -> k d);
1021 kdef_s = (fun (k,_) d -> k d);
b1b2de81 1022 kname_s = (fun (k,_) x -> k x);
34e49164
C
1023 kini_s = (fun (k,_) d -> k d);
1024 ktoplevel_s = (fun (k,_) p -> k p);
1025 knode_s = (fun (k,_) n -> k n);
1026 kinfo_s = (fun (k,_) i -> k i);
1027 kdefineval_s = (fun (k,_) x -> k x);
485bce71
C
1028 kstatementseq_s = (fun (k,_) x -> k x);
1029 kstatementseq_list_s = (fun (k,_) x -> k x);
1030 kcppdirective_s = (fun (k,_) x -> k x);
ae4735db 1031 }
34e49164
C
1032
1033let rec vk_expr_s = fun bigf expr ->
1034 let iif ii = vk_ii_s bigf ii in
1035 let rec exprf e = bigf.kexpr_s (k, bigf) e
ae4735db 1036 and k e =
34e49164 1037 let ((unwrap_e, typ), ii) = e in
91eba41f 1038 (* !!! don't analyse optional type !!!
ae4735db 1039 * old: typ +> map_option (vk_type_s bigf) in
34e49164 1040 *)
ae4735db
C
1041 let typ' = typ in
1042 let e' =
34e49164 1043 match unwrap_e with
b1b2de81 1044 | Ident (name) -> Ident (vk_name_s bigf name)
34e49164 1045 | Constant (c) -> Constant (c)
ae4735db 1046 | FunCall (e, es) ->
34e49164 1047 FunCall (exprf e,
ae4735db 1048 es +> List.map (fun (e,ii) ->
34e49164
C
1049 vk_argument_s bigf e, iif ii
1050 ))
ae4735db 1051
faf9a90c 1052 | CondExpr (e1, e2, e3) -> CondExpr (exprf e1, fmap exprf e2, exprf e3)
34e49164
C
1053 | Sequence (e1, e2) -> Sequence (exprf e1, exprf e2)
1054 | Assignment (e1, op, e2) -> Assignment (exprf e1, op, exprf e2)
ae4735db 1055
34e49164
C
1056 | Postfix (e, op) -> Postfix (exprf e, op)
1057 | Infix (e, op) -> Infix (exprf e, op)
1058 | Unary (e, op) -> Unary (exprf e, op)
1059 | Binary (e1, op, e2) -> Binary (exprf e1, op, exprf e2)
ae4735db 1060
1b9ae606
C
1061 | ArrayAccess (e1, e2) -> ArrayAccess (exprf e1, exprf e2)
1062 | RecordAccess (e, name) -> RecordAccess (exprf e, vk_name_s bigf name)
1063 | RecordPtAccess (e, name) -> RecordPtAccess (exprf e, vk_name_s bigf name)
34e49164 1064
1b9ae606 1065 | SizeOfExpr (e) -> SizeOfExpr (exprf e)
34e49164 1066 | SizeOfType (t) -> SizeOfType (vk_type_s bigf t)
1b9ae606 1067 | Cast (t, e) -> Cast (vk_type_s bigf t, exprf e)
34e49164 1068
ae4735db 1069 | StatementExpr (statxs, is) ->
34e49164 1070 StatementExpr (
485bce71 1071 vk_statement_sequencable_list_s bigf statxs,
34e49164 1072 iif is)
1b9ae606 1073 | Constructor (t, init) -> Constructor (vk_type_s bigf t, vk_ini_s bigf init)
ae4735db 1074
1b9ae606 1075 | ParenExpr (e) -> ParenExpr (exprf e)
34e49164 1076
1b9ae606
C
1077 | New (None, t) -> New (None, vk_argument_s bigf t)
1078 | New (Some ts, t) ->
1079 New (Some (ts +> List.map (fun (e,ii) ->
1080 vk_argument_s bigf e, iif ii)), vk_argument_s bigf t)
4dfbc1c2 1081 | Delete e -> Delete (vk_expr_s bigf e)
f59c9fb7 1082
34e49164
C
1083 in
1084 (e', typ'), (iif ii)
1085 in exprf expr
1086
b1b2de81 1087
ae4735db 1088and vk_argument_s bigf argument =
34e49164 1089 let iif ii = vk_ii_s bigf ii in
ae4735db 1090 let rec do_action = function
34e49164
C
1091 | (ActMisc ii) -> ActMisc (iif ii)
1092 in
1093 (match argument with
1094 | Left e -> Left (vk_expr_s bigf e)
1095 | Right (ArgType param) -> Right (ArgType (vk_param_s bigf param))
1096 | Right (ArgAction action) -> Right (ArgAction (do_action action))
1097 )
1098
b1b2de81
C
1099(* ------------------------------------------------------------------------ *)
1100
34e49164 1101
ae4735db 1102and vk_name_s = fun bigf ident ->
b1b2de81 1103 let iif ii = vk_ii_s bigf ii in
ae4735db
C
1104 let rec namef x = bigf.kname_s (k,bigf) x
1105 and k id =
b1b2de81
C
1106 (match id with
1107 | RegularName (s,ii) -> RegularName (s, iif ii)
ae4735db
C
1108 | CppConcatenatedName xs ->
1109 CppConcatenatedName (xs +> List.map (fun ((x,ii1), ii2) ->
b1b2de81
C
1110 (x, iif ii1), iif ii2
1111 ))
1112 | CppVariadicName (s, ii) -> CppVariadicName (s, iif ii)
ae4735db 1113 | CppIdentBuilder ((s,iis), xs) ->
b1b2de81 1114 CppIdentBuilder ((s, iif iis),
ae4735db 1115 xs +> List.map (fun ((x,iix), iicomma) ->
b1b2de81
C
1116 ((x, iif iix), iif iicomma)))
1117 )
1118 in
1119 namef ident
34e49164 1120
b1b2de81 1121(* ------------------------------------------------------------------------ *)
34e49164
C
1122
1123
1124
ae4735db
C
1125and vk_statement_s = fun bigf st ->
1126 let rec statf st = bigf.kstatement_s (k, bigf) st
1127 and k st =
34e49164 1128 let (unwrap_st, ii) = st in
ae4735db 1129 let st' =
34e49164 1130 match unwrap_st with
ae4735db 1131 | Labeled (Label (name, st)) ->
708f4980 1132 Labeled (Label (vk_name_s bigf name, statf st))
ae4735db 1133 | Labeled (Case (e, st)) ->
34e49164 1134 Labeled (Case ((vk_expr_s bigf) e , statf st))
ae4735db
C
1135 | Labeled (CaseRange (e, e2, st)) ->
1136 Labeled (CaseRange ((vk_expr_s bigf) e,
1137 (vk_expr_s bigf) e2,
34e49164
C
1138 statf st))
1139 | Labeled (Default st) -> Labeled (Default (statf st))
ae4735db 1140 | Compound statxs ->
485bce71 1141 Compound (vk_statement_sequencable_list_s bigf statxs)
34e49164
C
1142 | ExprStatement (None) -> ExprStatement (None)
1143 | ExprStatement (Some e) -> ExprStatement (Some ((vk_expr_s bigf) e))
ae4735db 1144 | Selection (If (e, st1, st2)) ->
34e49164 1145 Selection (If ((vk_expr_s bigf) e, statf st1, statf st2))
ae4735db 1146 | Selection (Switch (e, st)) ->
34e49164 1147 Selection (Switch ((vk_expr_s bigf) e, statf st))
ae4735db 1148 | Iteration (While (e, st)) ->
34e49164 1149 Iteration (While ((vk_expr_s bigf) e, statf st))
ae4735db 1150 | Iteration (DoWhile (st, e)) ->
34e49164 1151 Iteration (DoWhile (statf st, (vk_expr_s bigf) e))
755320b0
C
1152 | Iteration (For (first, (e2opt,i2), (e3opt,i3), st)) ->
1153 let first =
1154 match first with
1155 ForExp (e1opt,i1) ->
1156 let e1opt' = statf (mk_st (ExprStatement (e1opt)) i1) in
1157 let e1' = Ast_c.unwrap_st e1opt' in
1158 let i1' = Ast_c.get_ii_st_take_care e1opt' in
1159 (match e1' with
1160 ExprStatement x1 -> ForExp (x1,i1')
1161 | _ ->
1162 failwith
1163 "cant be here if iterator keep ExprStatement as is")
1164 | ForDecl decl -> ForDecl (vk_decl_s bigf decl) in
708f4980
C
1165 let e2opt' = statf (mk_st (ExprStatement (e2opt)) i2) in
1166 let e3opt' = statf (mk_st (ExprStatement (e3opt)) i3) in
1167
708f4980
C
1168 let e2' = Ast_c.unwrap_st e2opt' in
1169 let e3' = Ast_c.unwrap_st e3opt' in
708f4980
C
1170 let i2' = Ast_c.get_ii_st_take_care e2opt' in
1171 let i3' = Ast_c.get_ii_st_take_care e3opt' in
1172
755320b0
C
1173 (match (e2', e3') with
1174 | ((ExprStatement x2), ((ExprStatement x3))) ->
1175 Iteration (For (first, (x2,i2'), (x3,i3'), statf st))
708f4980 1176
34e49164
C
1177 | x -> failwith "cant be here if iterator keep ExprStatement as is"
1178 )
1179
ae4735db
C
1180 | Iteration (MacroIteration (s, es, st)) ->
1181 Iteration
34e49164
C
1182 (MacroIteration
1183 (s,
ae4735db 1184 es +> List.map (fun (e, ii) ->
34e49164 1185 vk_argument_s bigf e, vk_ii_s bigf ii
ae4735db 1186 ),
34e49164
C
1187 statf st
1188 ))
1189
ae4735db 1190
b1b2de81 1191 | Jump (Goto name) -> Jump (Goto (vk_name_s bigf name))
34e49164
C
1192 | Jump (((Continue|Break|Return) as x)) -> Jump (x)
1193 | Jump (ReturnExpr e) -> Jump (ReturnExpr ((vk_expr_s bigf) e))
1194 | Jump (GotoComputed e) -> Jump (GotoComputed (vk_expr_s bigf e));
1195
1196 | Decl decl -> Decl (vk_decl_s bigf decl)
1197 | Asm asmbody -> Asm (vk_asmbody_s bigf asmbody)
1198 | NestedFunc def -> NestedFunc (vk_def_s bigf def)
1199 | MacroStmt -> MacroStmt
1200 in
1201 st', vk_ii_s bigf ii
1202 in statf st
1203
485bce71 1204
ae4735db 1205and vk_statement_sequencable_s = fun bigf stseq ->
485bce71 1206 let f = bigf.kstatementseq_s in
ae4735db 1207 let k stseq =
485bce71
C
1208
1209 match stseq with
ae4735db 1210 | StmtElem st ->
485bce71 1211 StmtElem (vk_statement_s bigf st)
ae4735db 1212 | CppDirectiveStmt directive ->
485bce71 1213 CppDirectiveStmt (vk_cpp_directive_s bigf directive)
ae4735db 1214 | IfdefStmt ifdef ->
485bce71 1215 IfdefStmt (vk_ifdef_directive_s bigf ifdef)
ae4735db 1216 | IfdefStmt2 (ifdef, xxs) ->
485bce71 1217 let ifdef' = List.map (vk_ifdef_directive_s bigf) ifdef in
ae4735db 1218 let xxs' = xxs +> List.map (fun xs ->
b1b2de81 1219 xs +> vk_statement_sequencable_list_s bigf
485bce71
C
1220 )
1221 in
1222 IfdefStmt2(ifdef', xxs')
1223 in f (k, bigf) stseq
1224
ae4735db 1225and vk_statement_sequencable_list_s = fun bigf statxs ->
485bce71 1226 let f = bigf.kstatementseq_list_s in
ae4735db 1227 let k xs =
485bce71
C
1228 xs +> List.map (vk_statement_sequencable_s bigf)
1229 in
1230 f (k, bigf) statxs
485bce71
C
1231
1232
ae4735db
C
1233
1234and vk_asmbody_s = fun bigf (string_list, colon_list) ->
34e49164
C
1235 let iif ii = vk_ii_s bigf ii in
1236
1237 iif string_list,
ae4735db
C
1238 colon_list +> List.map (fun (Colon xs, ii) ->
1239 Colon
1240 (xs +> List.map (fun (x, iicomma) ->
34e49164 1241 (match x with
ae4735db 1242 | ColonMisc, ii -> ColonMisc, iif ii
34e49164
C
1243 | ColonExpr e, ii -> ColonExpr (vk_expr_s bigf e), iif ii
1244 ), iif iicomma
ae4735db
C
1245 )),
1246 iif ii
34e49164 1247 )
ae4735db
C
1248
1249
34e49164
C
1250
1251
0708f913 1252(* todo? a visitor for qualifier *)
ae4735db 1253and vk_type_s = fun bigf t ->
34e49164
C
1254 let rec typef t = bigf.ktype_s (k,bigf) t
1255 and iif ii = vk_ii_s bigf ii
ae4735db 1256 and k t =
34e49164
C
1257 let (q, t) = t in
1258 let (unwrap_q, iiq) = q in
faf9a90c
C
1259 (* strip_info_visitor needs iiq to be processed before iit *)
1260 let iif_iiq = iif iiq in
0708f913 1261 let q' = unwrap_q in
34e49164 1262 let (unwrap_t, iit) = t in
ae4735db 1263 let t' =
34e49164 1264 match unwrap_t with
f59c9fb7 1265 | NoType -> NoType
34e49164
C
1266 | BaseType x -> BaseType x
1267 | Pointer t -> Pointer (typef t)
ae4735db
C
1268 | Array (eopt, t) -> Array (fmap (vk_expr_s bigf) eopt, typef t)
1269 | FunctionType (returnt, paramst) ->
1270 FunctionType
1271 (typef returnt,
34e49164 1272 (match paramst with
ae4735db
C
1273 | (ts, (b, iihas3dots)) ->
1274 (ts +> List.map (fun (param,iicomma) ->
34e49164
C
1275 (vk_param_s bigf param, iif iicomma)),
1276 (b, iif iihas3dots))
1277 ))
1278
ae4735db 1279 | Enum (sopt, enumt) ->
c491d8ee 1280 Enum (sopt, vk_enum_fields_s bigf enumt)
ae4735db 1281 | StructUnion (sopt, su, fields) ->
34e49164
C
1282 StructUnion (sopt, su, vk_struct_fields_s bigf fields)
1283
1284
1285 | StructUnionName (s, structunion) -> StructUnionName (s, structunion)
1286 | EnumName s -> EnumName s
b1b2de81 1287 | TypeName (name, typ) -> TypeName (vk_name_s bigf name, typ)
34e49164
C
1288
1289 | ParenType t -> ParenType (typef t)
1290 | TypeOfExpr e -> TypeOfExpr (vk_expr_s bigf e)
1291 | TypeOfType t -> TypeOfType (typef t)
1292 in
ae4735db 1293 (q', iif_iiq),
faf9a90c 1294 (t', iif iit)
34e49164
C
1295
1296
1297 in typef t
1298
ae4735db 1299and vk_attribute_s = fun bigf attr ->
485bce71
C
1300 let iif ii = vk_ii_s bigf ii in
1301 match attr with
ae4735db 1302 | Attribute s, ii ->
485bce71
C
1303 Attribute s, iif ii
1304
1305
1306
ae4735db
C
1307and vk_decl_s = fun bigf d ->
1308 let f = bigf.kdecl_s in
34e49164 1309 let iif ii = vk_ii_s bigf ii in
ae4735db 1310 let rec k decl =
34e49164 1311 match decl with
ae4735db 1312 | DeclList (xs, ii) ->
34e49164 1313 DeclList (List.map aux xs, iif ii)
5427db06 1314 | MacroDecl ((s, args, ptvg),ii) ->
ae4735db
C
1315 MacroDecl
1316 ((s,
5427db06
C
1317 args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii),
1318 ptvg),
34e49164 1319 iif ii)
17ba0788
C
1320 | MacroDeclInit ((s, args, ini),ii) ->
1321 MacroDeclInit
1322 ((s,
1323 args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii),
1324 vk_ini_s bigf ini),
1325 iif ii)
34e49164
C
1326
1327
ae4735db
C
1328 and aux ({v_namei = var;
1329 v_type = t;
1330 v_type_bis = tbis;
1331 v_storage = sto;
1332 v_local= local;
1333 v_attr = attrs}, iicomma) =
1334 {v_namei =
1335 (var +> map_option (fun (name, iniopt) ->
1336 vk_name_s bigf name,
4dfbc1c2
C
1337 (match iniopt with
1338 Ast_c.NoInit -> iniopt
1339 | Ast_c.ValInit(iini,init) ->
1340 Ast_c.ValInit(vk_info_s bigf iini,vk_ini_s bigf init)
1341 | Ast_c.ConstrInit((init,ii)) ->
1342 let init =
1343 init +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii) in
1344 Ast_c.ConstrInit((init, List.map (vk_info_s bigf) ii)))
1345 ));
485bce71 1346 v_type = vk_type_s bigf t;
978fd7e5
C
1347 (* !!! dont go in semantic related stuff !!! *)
1348 v_type_bis = tbis;
485bce71
C
1349 v_storage = sto;
1350 v_local = local;
1351 v_attr = attrs +> List.map (vk_attribute_s bigf);
1352 },
1353 iif iicomma
34e49164 1354
ae4735db 1355 in f (k, bigf) d
34e49164 1356
190f1acf
C
1357and vk_decl_list_s = fun bigf decls ->
1358 decls +> List.map (vk_decl_s bigf)
1359
ae4735db 1360and vk_ini_s = fun bigf ini ->
34e49164 1361 let rec inif ini = bigf.kini_s (k,bigf) ini
ae4735db 1362 and k ini =
34e49164 1363 let (unwrap_ini, ii) = ini in
ae4735db 1364 let ini' =
34e49164
C
1365 match unwrap_ini with
1366 | InitExpr e -> InitExpr (vk_expr_s bigf e)
ae4735db
C
1367 | InitList initxs ->
1368 InitList (initxs +> List.map (fun (ini, ii) ->
1369 inif ini, vk_ii_s bigf ii)
34e49164
C
1370 )
1371
1372
ae4735db
C
1373 | InitDesignators (xs, e) ->
1374 InitDesignators
34e49164 1375 (xs +> List.map (vk_designator_s bigf),
ae4735db 1376 inif e
34e49164
C
1377 )
1378
1379 | InitFieldOld (s, e) -> InitFieldOld (s, inif e)
1380 | InitIndexOld (e1, e) -> InitIndexOld (vk_expr_s bigf e1, inif e)
1381
485bce71 1382
34e49164
C
1383 in ini', vk_ii_s bigf ii
1384 in inif ini
1385
1386
ae4735db 1387and vk_designator_s = fun bigf design ->
34e49164
C
1388 let iif ii = vk_ii_s bigf ii in
1389 let (designator, ii) = design in
1390 (match designator with
1391 | DesignatorField s -> DesignatorField s
1392 | DesignatorIndex e -> DesignatorIndex (vk_expr_s bigf e)
ae4735db 1393 | DesignatorRange (e1, e2) ->
34e49164
C
1394 DesignatorRange (vk_expr_s bigf e1, vk_expr_s bigf e2)
1395 ), iif ii
1396
1397
1398
1399
ae4735db 1400and vk_struct_fieldkinds_s = fun bigf onefield_multivars ->
485bce71 1401 let iif ii = vk_ii_s bigf ii in
ae4735db 1402
485bce71
C
1403 onefield_multivars +> List.map (fun (field, iicomma) ->
1404 (match field with
ae4735db
C
1405 | Simple (nameopt, t) ->
1406 Simple (Common.map_option (vk_name_s bigf) nameopt,
b1b2de81 1407 vk_type_s bigf t)
ae4735db
C
1408 | BitField (nameopt, t, info, expr) ->
1409 BitField (Common.map_option (vk_name_s bigf) nameopt,
1410 vk_type_s bigf t,
b1b2de81
C
1411 vk_info_s bigf info,
1412 vk_expr_s bigf expr)
485bce71
C
1413 ), iif iicomma
1414 )
1415
413ffc02 1416and vk_struct_field_s = fun bigf field ->
34e49164
C
1417 let iif ii = vk_ii_s bigf ii in
1418
413ffc02
C
1419 match field with
1420 (DeclarationField (FieldDeclList (onefield_multivars, iiptvirg))) ->
1421 DeclarationField
1422 (FieldDeclList
1423 (vk_struct_fieldkinds_s bigf onefield_multivars, iif iiptvirg))
1424 | EmptyField info -> EmptyField (vk_info_s bigf info)
1425 | MacroDeclField ((s, args),ii) ->
1426 MacroDeclField
1427 ((s,
1428 args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii)
1429 ),
1430 iif ii)
1431
1432 | CppDirectiveStruct directive ->
1433 CppDirectiveStruct (vk_cpp_directive_s bigf directive)
1434 | IfdefStruct ifdef ->
1435 IfdefStruct (vk_ifdef_directive_s bigf ifdef)
485bce71 1436
413ffc02 1437and vk_struct_fields_s = fun bigf fields ->
413ffc02 1438 fields +> List.map (vk_struct_field_s bigf)
34e49164 1439
c491d8ee
C
1440and vk_enum_fields_s = fun bigf enumt ->
1441 let iif ii = vk_ii_s bigf ii in
1442 enumt +> List.map (fun ((name, eopt), iicomma) ->
1443 vk_oneEnum_s bigf (name, eopt), iif iicomma)
1444
1445and vk_oneEnum_s = fun bigf oneEnum ->
1446 let (name,eopt) = oneEnum in
1447 (vk_name_s bigf name,
1448 eopt +> Common.fmap (fun (info, e) ->
1449 vk_info_s bigf info,
1450 vk_expr_s bigf e
1451 ))
34e49164 1452
ae4735db 1453and vk_def_s = fun bigf d ->
34e49164
C
1454 let f = bigf.kdef_s in
1455 let iif ii = vk_ii_s bigf ii in
ae4735db 1456 let rec k d =
34e49164 1457 match d with
708f4980 1458 | {f_name = name;
485bce71
C
1459 f_type = (returnt, (paramst, (b, iib)));
1460 f_storage = sto;
1461 f_body = statxs;
1462 f_attr = attrs;
91eba41f 1463 f_old_c_style = oldstyle;
ae4735db
C
1464 }, ii
1465 ->
708f4980 1466 {f_name = vk_name_s bigf name;
ae4735db
C
1467 f_type =
1468 (vk_type_s bigf returnt,
485bce71
C
1469 (paramst +> List.map (fun (param, iicomma) ->
1470 (vk_param_s bigf param, iif iicomma)
1471 ), (b, iif iib)));
1472 f_storage = sto;
ae4735db 1473 f_body =
485bce71 1474 vk_statement_sequencable_list_s bigf statxs;
ae4735db 1475 f_attr =
91eba41f 1476 attrs +> List.map (vk_attribute_s bigf);
ae4735db
C
1477 f_old_c_style =
1478 oldstyle +> Common.map_option (fun decls ->
91eba41f
C
1479 decls +> List.map (vk_decl_s bigf)
1480 );
485bce71 1481 },
34e49164
C
1482 iif ii
1483
ae4735db 1484 in f (k, bigf) d
34e49164 1485
ae4735db 1486and vk_toplevel_s = fun bigf p ->
34e49164
C
1487 let f = bigf.ktoplevel_s in
1488 let iif ii = vk_ii_s bigf ii in
ae4735db 1489 let rec k p =
34e49164
C
1490 match p with
1491 | Declaration decl -> Declaration (vk_decl_s bigf decl)
1492 | Definition def -> Definition (vk_def_s bigf def)
1493 | EmptyDef ii -> EmptyDef (iif ii)
ae4735db 1494 | MacroTop (s, xs, ii) ->
34e49164 1495 MacroTop
ae4735db
C
1496 (s,
1497 xs +> List.map (fun (elem, iicomma) ->
34e49164
C
1498 vk_argument_s bigf elem, iif iicomma
1499 ),
1500 iif ii
1501 )
485bce71
C
1502 | CppTop top -> CppTop (vk_cpp_directive_s bigf top)
1503 | IfdefTop ifdefdir -> IfdefTop (vk_ifdef_directive_s bigf ifdefdir)
34e49164
C
1504
1505 | NotParsedCorrectly ii -> NotParsedCorrectly (iif ii)
1506 | FinalDef info -> FinalDef (vk_info_s bigf info)
1b9ae606 1507 | Namespace (tls, ii) -> Namespace (List.map (vk_toplevel_s bigf) tls, ii)
34e49164
C
1508 in f (k, bigf) p
1509
ae4735db 1510and vk_program_s = fun bigf xs ->
485bce71
C
1511 xs +> List.map (vk_toplevel_s bigf)
1512
1513
1514and vk_cpp_directive_s = fun bigf top ->
1515 let iif ii = vk_ii_s bigf ii in
1516 let f = bigf.kcppdirective_s in
ae4735db
C
1517 let rec k top =
1518 match top with
485bce71
C
1519 (* go inside ? *)
1520 | Include {i_include = (s, ii);
1521 i_rel_pos = h_rel_pos;
1522 i_is_in_ifdef = b;
1523 i_content = copt;
ae4735db 1524 }
485bce71
C
1525 -> Include {i_include = (s, iif ii);
1526 i_rel_pos = h_rel_pos;
1527 i_is_in_ifdef = b;
ae4735db 1528 i_content = copt +> Common.map_option (fun (file, asts) ->
485bce71
C
1529 file, vk_program_s bigf asts
1530 );
1531 }
ae4735db
C
1532 | Define ((s,ii), (defkind, defval)) ->
1533 Define ((s, iif ii),
485bce71 1534 (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
485bce71
C
1535 | PragmaAndCo (ii) -> PragmaAndCo (iif ii)
1536
1537 in f (k, bigf) top
1538
ae4735db 1539and vk_ifdef_directive_s = fun bigf ifdef ->
485bce71
C
1540 let iif ii = vk_ii_s bigf ii in
1541 match ifdef with
1542 | IfdefDirective (ifkind, ii) -> IfdefDirective (ifkind, iif ii)
1543
1544
1545
ae4735db 1546and vk_define_kind_s = fun bigf defkind ->
34e49164 1547 match defkind with
ae4735db
C
1548 | DefineVar -> DefineVar
1549 | DefineFunc (params, ii) ->
1550 DefineFunc
1551 (params +> List.map (fun ((s,iis),iicomma) ->
34e49164
C
1552 ((s, vk_ii_s bigf iis), vk_ii_s bigf iicomma)
1553 ),
1554 vk_ii_s bigf ii
1555 )
3a314143 1556 | Undef -> Undef
34e49164
C
1557
1558
ae4735db 1559and vk_define_val_s = fun bigf x ->
34e49164
C
1560 let f = bigf.kdefineval_s in
1561 let iif ii = vk_ii_s bigf ii in
ae4735db 1562 let rec k x =
34e49164
C
1563 match x with
1564 | DefineExpr e -> DefineExpr (vk_expr_s bigf e)
1565 | DefineStmt st -> DefineStmt (vk_statement_s bigf st)
ae4735db 1566 | DefineDoWhileZero ((st,e),ii) ->
485bce71
C
1567 let st' = vk_statement_s bigf st in
1568 let e' = vk_expr_s bigf e in
1569 DefineDoWhileZero ((st',e'), iif ii)
34e49164
C
1570 | DefineFunction def -> DefineFunction (vk_def_s bigf def)
1571 | DefineType ty -> DefineType (vk_type_s bigf ty)
1572 | DefineText (s, ii) -> DefineText (s, iif ii)
1573 | DefineEmpty -> DefineEmpty
485bce71 1574 | DefineInit ini -> DefineInit (vk_ini_s bigf ini)
abad11c5
C
1575 (* christia: added multi *)
1576 | DefineMulti ds ->
1577 DefineMulti (List.map (vk_statement_s bigf) ds)
485bce71 1578
ae4735db 1579 | DefineTodo ->
91eba41f 1580 pr2_once "DefineTodo";
485bce71 1581 DefineTodo
34e49164
C
1582 in
1583 f (k, bigf) x
34e49164 1584
ae4735db
C
1585
1586and vk_info_s = fun bigf info ->
34e49164
C
1587 let rec infof ii = bigf.kinfo_s (k, bigf) ii
1588 and k i = i
1589 in
1590 infof info
1591
ae4735db 1592and vk_ii_s = fun bigf ii ->
34e49164
C
1593 List.map (vk_info_s bigf) ii
1594
1595(* ------------------------------------------------------------------------ *)
ae4735db 1596and vk_node_s = fun bigf node ->
34e49164
C
1597 let iif ii = vk_ii_s bigf ii in
1598 let infof info = vk_info_s bigf info in
1599
1600 let rec nodef n = bigf.knode_s (k, bigf) n
ae4735db 1601 and k node =
34e49164
C
1602 F.rewrap node (
1603 match F.unwrap node with
ae4735db 1604 | F.FunHeader (def) ->
91eba41f
C
1605 assert (null (fst def).f_body);
1606 F.FunHeader (vk_def_s bigf def)
ae4735db 1607
34e49164 1608 | F.Decl declb -> F.Decl (vk_decl_s bigf declb)
ae4735db 1609 | F.ExprStatement (st, (eopt, ii)) ->
34e49164 1610 F.ExprStatement (st, (eopt +> map_option (vk_expr_s bigf), iif ii))
ae4735db
C
1611
1612 | F.IfHeader (st, (e,ii)) ->
34e49164 1613 F.IfHeader (st, (vk_expr_s bigf e, iif ii))
ae4735db 1614 | F.SwitchHeader (st, (e,ii)) ->
34e49164 1615 F.SwitchHeader(st, (vk_expr_s bigf e, iif ii))
ae4735db 1616 | F.WhileHeader (st, (e,ii)) ->
34e49164 1617 F.WhileHeader (st, (vk_expr_s bigf e, iif ii))
ae4735db 1618 | F.DoWhileTail (e,ii) ->
34e49164
C
1619 F.DoWhileTail (vk_expr_s bigf e, iif ii)
1620
755320b0
C
1621 | F.ForHeader (st, ((first, (e2opt,i2), (e3opt,i3)), ii)) ->
1622 let first =
1623 match first with
1624 ForExp (e1opt,i1) ->
1625 ForExp (e1opt +> Common.map_option (vk_expr_s bigf), iif i1)
1626 | ForDecl decl -> ForDecl (vk_decl_s bigf decl) in
1627
34e49164 1628 F.ForHeader (st,
755320b0 1629 ((first,
34e49164
C
1630 (e2opt +> Common.map_option (vk_expr_s bigf), iif i2),
1631 (e3opt +> Common.map_option (vk_expr_s bigf), iif i3)),
1632 iif ii))
1633
ae4735db 1634 | F.MacroIterHeader (st, ((s,es), ii)) ->
34e49164
C
1635 F.MacroIterHeader
1636 (st,
1637 ((s, es +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii)),
1638 iif ii))
1639
ae4735db
C
1640
1641 | F.ReturnExpr (st, (e,ii)) ->
34e49164 1642 F.ReturnExpr (st, (vk_expr_s bigf e, iif ii))
ae4735db 1643
34e49164 1644 | F.Case (st, (e,ii)) -> F.Case (st, (vk_expr_s bigf e, iif ii))
ae4735db 1645 | F.CaseRange (st, ((e1, e2),ii)) ->
34e49164
C
1646 F.CaseRange (st, ((vk_expr_s bigf e1, vk_expr_s bigf e2), iif ii))
1647
1648 | F.CaseNode i -> F.CaseNode i
1649
ae4735db 1650 | F.DefineHeader((s,ii), (defkind)) ->
34e49164
C
1651 F.DefineHeader ((s, iif ii), (vk_define_kind_s bigf defkind))
1652
1653 | F.DefineExpr e -> F.DefineExpr (vk_expr_s bigf e)
1654 | F.DefineType ft -> F.DefineType (vk_type_s bigf ft)
ae4735db 1655 | F.DefineDoWhileZeroHeader ((),ii) ->
34e49164 1656 F.DefineDoWhileZeroHeader ((),iif ii)
485bce71
C
1657 | F.DefineTodo -> F.DefineTodo
1658
1659 | F.Include {i_include = (s, ii);
1660 i_rel_pos = h_rel_pos;
1661 i_is_in_ifdef = b;
1662 i_content = copt;
ae4735db
C
1663 }
1664 ->
b1b2de81 1665 assert (copt =*= None);
485bce71
C
1666 F.Include {i_include = (s, iif ii);
1667 i_rel_pos = h_rel_pos;
1668 i_is_in_ifdef = b;
1669 i_content = copt;
1670 }
34e49164 1671
ae4735db
C
1672 | F.MacroTop (s, args, ii) ->
1673 F.MacroTop
34e49164
C
1674 (s,
1675 args +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii),
1676 iif ii)
1677
1678
1679 | F.MacroStmt (st, ((),ii)) -> F.MacroStmt (st, ((),iif ii))
1680 | F.Asm (st, (body,ii)) -> F.Asm (st, (vk_asmbody_s bigf body,iif ii))
1681
1682 | F.Break (st,((),ii)) -> F.Break (st,((),iif ii))
1683 | F.Continue (st,((),ii)) -> F.Continue (st,((),iif ii))
1684 | F.Default (st,((),ii)) -> F.Default (st,((),iif ii))
1685 | F.Return (st,((),ii)) -> F.Return (st,((),iif ii))
ae4735db 1686 | F.Goto (st, name, ((),ii)) ->
b1b2de81 1687 F.Goto (st, vk_name_s bigf name, ((),iif ii))
ae4735db 1688 | F.Label (st, name, ((),ii)) ->
b1b2de81 1689 F.Label (st, vk_name_s bigf name, ((),iif ii))
34e49164
C
1690 | F.EndStatement iopt -> F.EndStatement (map_option infof iopt)
1691 | F.DoHeader (st, info) -> F.DoHeader (st, infof info)
1692 | F.Else info -> F.Else (infof info)
1693 | F.SeqEnd (i, info) -> F.SeqEnd (i, infof info)
1694 | F.SeqStart (st, i, info) -> F.SeqStart (st, i, infof info)
1695
485bce71
C
1696 | F.IfdefHeader (info) -> F.IfdefHeader (vk_ifdef_directive_s bigf info)
1697 | F.IfdefElse (info) -> F.IfdefElse (vk_ifdef_directive_s bigf info)
1698 | F.IfdefEndif (info) -> F.IfdefEndif (vk_ifdef_directive_s bigf info)
1699
34e49164
C
1700 | (
1701 (
1702 F.TopNode|F.EndNode|
951c7801
C
1703 F.ErrorExit|F.Exit|F.Enter|F.LoopFallThroughNode|F.FallThroughNode|
1704 F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
34e49164
C
1705 F.Fake
1706 ) as x) -> x
1707
1708
1709 )
1710 in
1711 nodef node
ae4735db 1712
34e49164 1713(* ------------------------------------------------------------------------ *)
ae4735db 1714and vk_param_s = fun bigf param ->
34e49164 1715 let iif ii = vk_ii_s bigf ii in
b1b2de81
C
1716 let {p_namei = swrapopt; p_register = (b, iib); p_type=ft} = param in
1717 { p_namei = swrapopt +> Common.map_option (vk_name_s bigf);
1718 p_register = (b, iif iib);
1719 p_type = vk_type_s bigf ft;
1720 }
faf9a90c 1721
ae4735db 1722let vk_arguments_s = fun bigf args ->
34e49164
C
1723 let iif ii = vk_ii_s bigf ii in
1724 args +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii)
1725
8f657093
C
1726let vk_inis_s = fun bigf inis ->
1727 let iif ii = vk_ii_s bigf ii in
1728 inis +> List.map (fun (e, ii) -> vk_ini_s bigf e, iif ii)
1729
ae4735db 1730let vk_params_s = fun bigf args ->
34e49164
C
1731 let iif ii = vk_ii_s bigf ii in
1732 args +> List.map (fun (p,ii) -> vk_param_s bigf p, iif ii)
1733
ae4735db 1734let vk_cst_s = fun bigf (cst, ii) ->
34e49164
C
1735 let iif ii = vk_ii_s bigf ii in
1736 (match cst with
ae4735db 1737 | Left cst -> Left cst
34e49164
C
1738 | Right s -> Right s
1739 ), iif ii
c491d8ee
C
1740
1741(* ------------------------------------------------------------------------ *)
1742
1743let vk_splitted_s element = fun bigf args_splitted ->
1744 let iif ii = vk_ii_s bigf ii in
1745 args_splitted +> List.map (function
1746 | Left arg -> Left (element bigf arg)
1747 | Right ii -> Right (iif ii)
1748 )
1749
1750let vk_args_splitted_s = vk_splitted_s vk_argument_s
1751let vk_params_splitted_s = vk_splitted_s vk_param_s
1752let vk_define_params_splitted_s =
1753 vk_splitted_s (fun bigf (s,ii) -> (s,vk_ii_s bigf ii))
1754let vk_enum_fields_splitted_s = vk_splitted_s vk_oneEnum_s
1755let vk_inis_splitted_s = vk_splitted_s vk_ini_s