Release coccinelle-0.1.2
[bpt/coccinelle.git] / parsing_c / visitor_c.ml
CommitLineData
485bce71 1(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
34e49164
C
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License (GPL)
5 * version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * file license.txt for more details.
11 *)
12open Common
13
14
15open Ast_c
16module F = Control_flow_c
17
18(*****************************************************************************)
19(* Functions to visit the Ast, and now also the CFG nodes *)
20(*****************************************************************************)
21
22
23(* Visitor based on continuation. Cleaner than the one based on mutable
485bce71
C
24 * pointer functions that I had before.
25 * src: based on a (vague) idea from Remy Douence.
34e49164
C
26 *
27 *
28 *
29 * Diff with Julia's visitor ? She does:
30 *
31 * let ident r k i =
32 * ...
33 * let expression r k e =
34 * ...
35 * ... (List.map r.V0.combiner_expression expr_list) ...
36 * ...
37 * let res = V0.combiner bind option_default
38 * mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
39 * donothing donothing donothing donothing
40 * ident expression typeC donothing parameter declaration statement
41 * donothing in
42 * ...
43 * collect_unitary_nonunitary
44 * (List.concat (List.map res.V0.combiner_top_level t))
45 *
46 *
47 *
48 * So she has to remember at which position you must put the 'expression'
49 * function. I use record which is easier.
50 *
51 * When she calls recursively, her res.V0.combiner_xxx does not take bigf
52 * in param whereas I do
53 * | F.Decl decl -> Visitor_c.vk_decl bigf decl
54 * And with the record she gets, she does not have to do my
55 * multiple defs of function such as 'let al_type = V0.vk_type_s bigf'
56 *
57 * The code of visitor.ml is cleaner with julia because mutual recursive calls
58 * are clean such as ... 'expression e' ... and not 'f (k, bigf) e'
59 * or 'vk_expr bigf e'.
60 *
61 * So it is very dual:
62 * - I give a record but then I must handle bigf.
63 * - She gets a record, and gives a list of function
64 *
65 *)
66
67
68(* old: first version (only visiting expr)
69
70let (iter_expr:((expression -> unit) -> expression -> unit) -> expression -> unit)
71 = fun f expr ->
72 let rec k e =
73 match e with
74 | Constant c -> ()
75 | FunCall (e, es) -> f k e; List.iter (f k) es
76 | CondExpr (e1, e2, e3) -> f k e1; f k e2; f k e3
77 | Sequence (e1, e2) -> f k e1; f k e2;
78 | Assignment (e1, op, e2) -> f k e1; f k e2;
79
80 | Postfix (e, op) -> f k e
81 | Infix (e, op) -> f k e
82 | Unary (e, op) -> f k e
83 | Binary (e1, op, e2) -> f k e1; f k e2;
84
85 | ArrayAccess (e1, e2) -> f k e1; f k e2;
86 | RecordAccess (e, s) -> f k e
87 | RecordPtAccess (e, s) -> f k e
88
89 | SizeOfExpr e -> f k e
90 | SizeOfType t -> ()
91 | _ -> failwith "to complete"
92
93 in f k expr
94
95let ex1 = Sequence (Sequence (Constant (Ident "1"), Constant (Ident "2")),
96 Constant (Ident "4"))
97let test =
98 iter_expr (fun k e -> match e with
99 | Constant (Ident x) -> Common.pr2 x
100 | rest -> k rest
101 ) ex1
102==>
1031
1042
1054
106
107*)
108
109(*****************************************************************************)
110(* Side effect style visitor *)
111(*****************************************************************************)
112
113(* Visitors for all langage concept, not just for expression.
114 *
115 * Note that I don't visit necesserally in the order of the token
116 * found in the original file. So don't assume such hypothesis!
485bce71
C
117 *
118 * todo? parameter ? onedecl ?
34e49164
C
119 *)
120type visitor_c =
121 {
122 kexpr: (expression -> unit) * visitor_c -> expression -> unit;
123 kstatement: (statement -> unit) * visitor_c -> statement -> unit;
124 ktype: (fullType -> unit) * visitor_c -> fullType -> unit;
125
126 kdecl: (declaration -> unit) * visitor_c -> declaration -> unit;
127 kdef: (definition -> unit) * visitor_c -> definition -> unit;
128 kini: (initialiser -> unit) * visitor_c -> initialiser -> unit;
129
485bce71
C
130 kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
131 kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
132 kstatementseq: (statement_sequencable -> unit) * visitor_c -> statement_sequencable -> unit;
34e49164
C
133
134 (* CFG *)
135 knode: (F.node -> unit) * visitor_c -> F.node -> unit;
136 (* AST *)
137 ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
485bce71
C
138
139 kinfo: (info -> unit) * visitor_c -> info -> unit;
34e49164
C
140 }
141
142let default_visitor_c =
143 { kexpr = (fun (k,_) e -> k e);
144 kstatement = (fun (k,_) st -> k st);
145 ktype = (fun (k,_) t -> k t);
146 kdecl = (fun (k,_) d -> k d);
147 kdef = (fun (k,_) d -> k d);
148 kini = (fun (k,_) ie -> k ie);
149 kinfo = (fun (k,_) ii -> k ii);
150 knode = (fun (k,_) n -> k n);
151 ktoplevel = (fun (k,_) p -> k p);
485bce71
C
152 kcppdirective = (fun (k,_) p -> k p);
153 kdefineval = (fun (k,_) p -> k p);
154 kstatementseq = (fun (k,_) p -> k p);
34e49164
C
155 }
156
485bce71
C
157
158(* ------------------------------------------------------------------------ *)
159
160
34e49164
C
161let rec vk_expr = fun bigf expr ->
162 let iif ii = vk_ii bigf ii in
163
164 let rec exprf e = bigf.kexpr (k,bigf) e
165 (* dont go in _typ *)
166 and k ((e,_typ), ii) =
167 iif ii;
168 match e with
169 | Ident (s) -> ()
170 | Constant (c) -> ()
171 | FunCall (e, es) ->
172 exprf e;
485bce71 173 vk_argument_list bigf es;
34e49164
C
174 | CondExpr (e1, e2, e3) ->
175 exprf e1; do_option (exprf) e2; exprf e3
176 | Sequence (e1, e2) -> exprf e1; exprf e2;
177 | Assignment (e1, op, e2) -> exprf e1; exprf e2;
178
179 | Postfix (e, op) -> exprf e
180 | Infix (e, op) -> exprf e
181 | Unary (e, op) -> exprf e
182 | Binary (e1, op, e2) -> exprf e1; exprf e2;
183
184 | ArrayAccess (e1, e2) -> exprf e1; exprf e2;
185 | RecordAccess (e, s) -> exprf e
186 | RecordPtAccess (e, s) -> exprf e
187
188 | SizeOfExpr (e) -> exprf e
189 | SizeOfType (t) -> vk_type bigf t
190 | Cast (t, e) -> vk_type bigf t; exprf e
191
192 (* old: | StatementExpr (((declxs, statxs), is)), is2 ->
193 * List.iter (vk_decl bigf) declxs;
194 * List.iter (vk_statement bigf) statxs
195 *)
196 | StatementExpr ((statxs, is)) ->
197 iif is;
485bce71 198 statxs +> List.iter (vk_statement_sequencable bigf);
34e49164
C
199
200 (* TODO, we will certainly have to then do a special visitor for
201 * initializer
202 *)
203 | Constructor (t, initxs) ->
204 vk_type bigf t;
205 initxs +> List.iter (fun (ini, ii) ->
206 vk_ini bigf ini;
207 vk_ii bigf ii;
208 )
209
210 | ParenExpr (e) -> exprf e
211
212
213 in exprf expr
214
34e49164
C
215
216
217
218
485bce71 219and vk_statement = fun bigf (st: Ast_c.statement) ->
34e49164
C
220 let iif ii = vk_ii bigf ii in
221
222 let rec statf x = bigf.kstatement (k,bigf) x
223 and k st =
224 let (unwrap_st, ii) = st in
225 iif ii;
226 match unwrap_st with
227 | Labeled (Label (s, st)) -> statf st;
228 | Labeled (Case (e, st)) -> vk_expr bigf e; statf st;
229 | Labeled (CaseRange (e, e2, st)) ->
230 vk_expr bigf e; vk_expr bigf e2; statf st;
231 | Labeled (Default st) -> statf st;
232
485bce71
C
233 | Compound statxs ->
234 statxs +> List.iter (vk_statement_sequencable bigf)
34e49164
C
235 | ExprStatement (eopt) -> do_option (vk_expr bigf) eopt;
236
237 | Selection (If (e, st1, st2)) ->
238 vk_expr bigf e; statf st1; statf st2;
34e49164
C
239 | Selection (Switch (e, st)) ->
240 vk_expr bigf e; statf st;
241 | Iteration (While (e, st)) ->
242 vk_expr bigf e; statf st;
243 | Iteration (DoWhile (st, e)) -> statf st; vk_expr bigf e;
244 | Iteration (For ((e1opt,i1), (e2opt,i2), (e3opt,i3), st)) ->
245 statf (ExprStatement (e1opt),i1);
246 statf (ExprStatement (e2opt),i2);
247 statf (ExprStatement (e3opt),i3);
248 statf st;
249
250 | Iteration (MacroIteration (s, es, st)) ->
485bce71 251 vk_argument_list bigf es;
34e49164
C
252 statf st;
253
254 | Jump (Goto s) -> ()
255 | Jump ((Continue|Break|Return)) -> ()
256 | Jump (ReturnExpr e) -> vk_expr bigf e;
257 | Jump (GotoComputed e) -> vk_expr bigf e;
258
259 | Decl decl -> vk_decl bigf decl
260 | Asm asmbody -> vk_asmbody bigf asmbody
261 | NestedFunc def -> vk_def bigf def
262 | MacroStmt -> ()
263
264 in statf st
265
485bce71
C
266and vk_statement_sequencable = fun bigf stseq ->
267 let f = bigf.kstatementseq in
268
269 let rec k stseq =
270 match stseq with
271 | StmtElem st -> vk_statement bigf st
272 | CppDirectiveStmt directive ->
273 vk_cpp_directive bigf directive
274 | IfdefStmt ifdef ->
275 vk_ifdef_directive bigf ifdef
276 | IfdefStmt2 (ifdef, xxs) ->
277 ifdef +> List.iter (vk_ifdef_directive bigf);
278 xxs +> List.iter (fun xs ->
279 xs +> List.iter (vk_statement_sequencable bigf)
280 )
281
282 in f (k, bigf) stseq
283
34e49164 284
34e49164
C
285
286and vk_type = fun bigf t ->
287 let iif ii = vk_ii bigf ii in
288
289 let rec typef x = bigf.ktype (k, bigf) x
290 and k t =
291 let (q, t) = t in
292 let (unwrap_q, iiq) = q in
293 let (unwrap_t, iit) = t in
294 iif iiq;
295 iif iit;
296 match unwrap_t with
297 | BaseType _ -> ()
298 | Pointer t -> typef t
299 | Array (eopt, t) ->
300 do_option (vk_expr bigf) eopt;
301 typef t
302 | FunctionType (returnt, paramst) ->
303 typef returnt;
304 (match paramst with
305 | (ts, (b,iihas3dots)) ->
306 iif iihas3dots;
485bce71 307 vk_param_list bigf ts
34e49164
C
308 )
309
310 | Enum (sopt, enumt) ->
311 enumt +> List.iter (fun (((s, eopt),ii_s_eq), iicomma) ->
312 iif ii_s_eq; iif iicomma;
313 eopt +> do_option (vk_expr bigf)
314 );
315
316 | StructUnion (sopt, _su, fields) ->
317 vk_struct_fields bigf fields
318
319 | StructUnionName (s, structunion) -> ()
320 | EnumName s -> ()
321
322 (* dont go in _typ *)
323 | TypeName (s, _typ) -> ()
324
325 | ParenType t -> typef t
326 | TypeOfExpr e -> vk_expr bigf e
327 | TypeOfType t -> typef t
328
329 in typef t
330
485bce71
C
331
332and vk_attribute = fun bigf attr ->
333 let iif ii = vk_ii bigf ii in
334 match attr with
335 | Attribute s, ii ->
336 iif ii
337
338
339(* ------------------------------------------------------------------------ *)
340
34e49164
C
341and vk_decl = fun bigf d ->
342 let iif ii = vk_ii bigf ii in
343
344 let f = bigf.kdecl in
345 let rec k decl =
346 match decl with
347 | DeclList (xs,ii) -> iif ii; List.iter aux xs
348 | MacroDecl ((s, args),ii) ->
349 iif ii;
485bce71 350 vk_argument_list bigf args;
34e49164
C
351
352
485bce71
C
353 and aux ({v_namei = var; v_type = t;
354 v_storage = _sto; v_attr = attrs}, iicomma) =
34e49164
C
355 iif iicomma;
356 vk_type bigf t;
485bce71 357 attrs +> List.iter (vk_attribute bigf);
34e49164
C
358 var +> do_option (fun ((s, ini), ii_s_ini) ->
359 iif ii_s_ini;
360 ini +> do_option (vk_ini bigf)
361 );
362 in f (k, bigf) d
363
364and vk_ini = fun bigf ini ->
365 let iif ii = vk_ii bigf ii in
366
367 let rec inif x = bigf.kini (k, bigf) x
368 and k (ini, iini) =
369 iif iini;
370 match ini with
371 | InitExpr e -> vk_expr bigf e
372 | InitList initxs ->
373 initxs +> List.iter (fun (ini, ii) ->
374 inif ini;
375 iif ii;
376 )
377 | InitDesignators (xs, e) ->
378 xs +> List.iter (vk_designator bigf);
379 inif e
380
381 | InitFieldOld (s, e) -> inif e
382 | InitIndexOld (e1, e) ->
383 vk_expr bigf e1; inif e
384
485bce71 385
34e49164
C
386 in inif ini
387
388
389and vk_designator = fun bigf design ->
390 let iif ii = vk_ii bigf ii in
391 let (designator, ii) = design in
392 iif ii;
393 match designator with
394 | DesignatorField s -> ()
395 | DesignatorIndex e -> vk_expr bigf e
396 | DesignatorRange (e1, e2) -> vk_expr bigf e1; vk_expr bigf e2
397
485bce71
C
398
399(* ------------------------------------------------------------------------ *)
400
34e49164
C
401and vk_struct_fields = fun bigf fields ->
402 let iif ii = vk_ii bigf ii in
403
404 fields +> List.iter (fun (xfield, ii) ->
405 iif ii;
406 match xfield with
485bce71
C
407 | DeclarationField
408 (FieldDeclList (onefield_multivars, iiptvirg)) ->
409 vk_struct_fieldkinds bigf onefield_multivars;
410 iif iiptvirg;
34e49164 411 | EmptyField -> ()
485bce71
C
412 | MacroStructDeclTodo ->
413 pr2 "MacroStructDeclTodo";
414 ()
415
416 | CppDirectiveStruct directive ->
417 vk_cpp_directive bigf directive
418 | IfdefStruct ifdef ->
419 vk_ifdef_directive bigf ifdef
420
34e49164
C
421 )
422
485bce71 423and vk_struct_fieldkinds = fun bigf onefield_multivars ->
34e49164
C
424 let iif ii = vk_ii bigf ii in
425 onefield_multivars +> List.iter (fun (field, iicomma) ->
426 iif iicomma;
427 match field with
428 | Simple (s, t), ii -> iif ii; vk_type bigf t;
429 | BitField (sopt, t, expr), ii ->
430 iif ii;
431 vk_expr bigf expr;
432 vk_type bigf t
433 )
434
485bce71 435(* ------------------------------------------------------------------------ *)
34e49164
C
436
437
438and vk_def = fun bigf d ->
439 let iif ii = vk_ii bigf ii in
440
441 let f = bigf.kdef in
442 let rec k d =
443 match d with
485bce71
C
444 | {f_name = s;
445 f_type = (returnt, (paramst, (b, iib)));
446 f_storage = sto;
447 f_body = statxs;
448 f_attr = attrs;
449 }, ii
450 ->
34e49164
C
451 iif ii;
452 iif iib;
485bce71 453 attrs +> List.iter (vk_attribute bigf);
34e49164
C
454 vk_type bigf returnt;
455 paramst +> List.iter (fun (param,iicomma) ->
456 vk_param bigf param;
457 iif iicomma;
458 );
485bce71 459 statxs +> List.iter (vk_statement_sequencable bigf)
34e49164
C
460 in f (k, bigf) d
461
462
463
464
465and vk_toplevel = fun bigf p ->
466 let f = bigf.ktoplevel in
467 let iif ii = vk_ii bigf ii in
468 let rec k p =
469 match p with
470 | Declaration decl -> (vk_decl bigf decl)
471 | Definition def -> (vk_def bigf def)
472 | EmptyDef ii -> iif ii
473 | MacroTop (s, xs, ii) ->
485bce71
C
474 vk_argument_list bigf xs;
475 iif ii
476
477 | CppTop top -> vk_cpp_directive bigf top
478 | IfdefTop ifdefdir -> vk_ifdef_directive bigf ifdefdir
34e49164 479
485bce71
C
480 | NotParsedCorrectly ii -> iif ii
481 | FinalDef info -> vk_info bigf info
482 in f (k, bigf) p
483
484and vk_program = fun bigf xs ->
485 xs +> List.iter (vk_toplevel bigf)
486
487and vk_ifdef_directive bigf directive =
488 let iif ii = vk_ii bigf ii in
489 match directive with
490 | IfdefDirective (ifkind, ii) -> iif ii
491
492
493and vk_cpp_directive bigf directive =
494 let iif ii = vk_ii bigf ii in
495 let f = bigf.kcppdirective in
496 let rec k directive =
497 match directive with
498 | Include {i_include = (s, ii);
499 i_content = copt;
500 }
501 ->
502 (* go inside ? *)
503 iif ii;
504 copt +> Common.do_option (fun (file, asts) ->
505 vk_program bigf asts
506 );
34e49164
C
507 | Define ((s,ii), (defkind, defval)) ->
508 iif ii;
509 vk_define_kind bigf defkind;
510 vk_define_val bigf defval
485bce71
C
511 | Undef (s, ii) ->
512 iif ii
513 | PragmaAndCo (ii) ->
514 iif ii
515 in f (k, bigf) directive
34e49164 516
34e49164
C
517
518and vk_define_kind bigf defkind =
519 match defkind with
520 | DefineVar -> ()
521 | DefineFunc (params, ii) ->
522 vk_ii bigf ii;
523 params +> List.iter (fun ((s,iis), iicomma) ->
524 vk_ii bigf iis;
525 vk_ii bigf iicomma;
526 )
527
528and vk_define_val bigf defval =
485bce71
C
529 let f = bigf.kdefineval in
530
531 let rec k defval =
34e49164
C
532 match defval with
533 | DefineExpr e ->
534 vk_expr bigf e
535 | DefineStmt stmt -> vk_statement bigf stmt
485bce71 536 | DefineDoWhileZero ((stmt, e), ii) ->
34e49164 537 vk_statement bigf stmt;
485bce71 538 vk_expr bigf e;
34e49164
C
539 vk_ii bigf ii
540 | DefineFunction def -> vk_def bigf def
541 | DefineType ty -> vk_type bigf ty
542 | DefineText (s, ii) -> vk_ii bigf ii
543 | DefineEmpty -> ()
485bce71
C
544 | DefineInit ini -> vk_ini bigf ini
545
546 | DefineTodo ->
547 pr2 "DefineTodo";
548 ()
549 in f (k, bigf) defval
550
34e49164
C
551
552
553
554(* ------------------------------------------------------------------------ *)
555(* Now keep fullstatement inside the control flow node,
556 * so that can then get in a MetaStmtVar the fullstatement to later
557 * pp back when the S is in a +. But that means that
558 * Exp will match an Ifnode even if there is no such exp
559 * inside the condition of the Ifnode (because the exp may
560 * be deeper, in the then branch). So have to not visit
561 * all inside a node anymore.
562 *
485bce71 563 * update: j'ai choisi d'accrocher au noeud du CFG a la
34e49164
C
564 * fois le fullstatement et le partialstatement et appeler le
565 * visiteur que sur le partialstatement.
566 *)
567
568and vk_node = fun bigf node ->
569 let iif ii = vk_ii bigf ii in
570 let infof info = vk_info bigf info in
571
572 let f = bigf.knode in
573 let rec k n =
574 match F.unwrap n with
575
485bce71
C
576 | F.FunHeader ({f_name =idb;
577 f_type = (rett, (paramst,(isvaargs,iidotsb)));
578 f_storage = stob;
579 f_body = body;
580 f_attr = attrs},ii) ->
581
582 assert(null body);
583 iif ii;
584 iif iidotsb;
585 attrs +> List.iter (vk_attribute bigf);
34e49164
C
586 vk_type bigf rett;
587 paramst +> List.iter (fun (param, iicomma) ->
588 vk_param bigf param;
589 iif iicomma;
590 );
591
592
593 | F.Decl decl -> vk_decl bigf decl
594 | F.ExprStatement (st, (eopt, ii)) ->
595 iif ii;
596 eopt +> do_option (vk_expr bigf)
597
598 | F.IfHeader (_, (e,ii))
599 | F.SwitchHeader (_, (e,ii))
600 | F.WhileHeader (_, (e,ii))
601 | F.DoWhileTail (e,ii) ->
602 iif ii;
603 vk_expr bigf e
604
605 | F.ForHeader (_st, (((e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) ->
606 iif i1; iif i2; iif i3;
607 iif ii;
608 e1opt +> do_option (vk_expr bigf);
609 e2opt +> do_option (vk_expr bigf);
610 e3opt +> do_option (vk_expr bigf);
611 | F.MacroIterHeader (_s, ((s,es), ii)) ->
612 iif ii;
485bce71 613 vk_argument_list bigf es;
34e49164
C
614
615 | F.ReturnExpr (_st, (e,ii)) -> iif ii; vk_expr bigf e
616
617 | F.Case (_st, (e,ii)) -> iif ii; vk_expr bigf e
618 | F.CaseRange (_st, ((e1, e2),ii)) ->
619 iif ii; vk_expr bigf e1; vk_expr bigf e2
620
621
622 | F.CaseNode i -> ()
623
624 | F.DefineExpr e -> vk_expr bigf e
625 | F.DefineType ft -> vk_type bigf ft
626 | F.DefineHeader ((s,ii), (defkind)) ->
627 iif ii;
628 vk_define_kind bigf defkind;
629
630 | F.DefineDoWhileZeroHeader (((),ii)) -> iif ii
485bce71
C
631 | F.DefineTodo ->
632 pr2 "DefineTodo";
633 ()
634
34e49164 635
485bce71 636 | F.Include {i_include = (s, ii);} -> iif ii;
34e49164
C
637
638 | F.MacroTop (s, args, ii) ->
639 iif ii;
485bce71 640 vk_argument_list bigf args
34e49164 641
485bce71
C
642 | F.IfdefHeader (info) -> vk_ifdef_directive bigf info
643 | F.IfdefElse (info) -> vk_ifdef_directive bigf info
644 | F.IfdefEndif (info) -> vk_ifdef_directive bigf info
34e49164
C
645
646 | F.Break (st,((),ii)) -> iif ii
647 | F.Continue (st,((),ii)) -> iif ii
648 | F.Default (st,((),ii)) -> iif ii
649 | F.Return (st,((),ii)) -> iif ii
650 | F.Goto (st, (s,ii)) -> iif ii
651 | F.Label (st, (s,ii)) -> iif ii
485bce71 652
34e49164 653 | F.DoHeader (st, info) -> infof info
485bce71 654
34e49164 655 | F.Else info -> infof info
485bce71
C
656 | F.EndStatement iopt -> do_option infof iopt
657
34e49164
C
658 | F.SeqEnd (i, info) -> infof info
659 | F.SeqStart (st, i, info) -> infof info
660
661 | F.MacroStmt (st, ((),ii)) -> iif ii
662 | F.Asm (st, (asmbody,ii)) ->
663 iif ii;
664 vk_asmbody bigf asmbody
665
666 | (
667 F.TopNode|F.EndNode|
668 F.ErrorExit|F.Exit|F.Enter|
669 F.FallThroughNode|F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
670 F.Fake
671 ) -> ()
672
673
674
675 in
676 f (k, bigf) node
677
678(* ------------------------------------------------------------------------ *)
679and vk_info = fun bigf info ->
680 let rec infof ii = bigf.kinfo (k, bigf) ii
681 and k i = ()
682 in
683 infof info
684
685and vk_ii = fun bigf ii ->
686 List.iter (vk_info bigf) ii
687
688
485bce71
C
689(* ------------------------------------------------------------------------ *)
690and vk_argument = fun bigf arg ->
691 let rec do_action = function
692 | (ActMisc ii) -> vk_ii bigf ii
693 in
694 match arg with
695 | Left e -> (vk_expr bigf) e
696 | Right (ArgType param) -> vk_param bigf param
697 | Right (ArgAction action) -> do_action action
698
699and vk_argument_list = fun bigf es ->
700 let iif ii = vk_ii bigf ii in
701 es +> List.iter (fun (e, ii) ->
702 iif ii;
703 vk_argument bigf e
704 )
705
706
707
34e49164
C
708and vk_param = fun bigf (((b, s, t), ii_b_s)) ->
709 let iif ii = vk_ii bigf ii in
710 iif ii_b_s;
711 vk_type bigf t
712
485bce71
C
713and vk_param_list = fun bigf ts ->
714 let iif ii = vk_ii bigf ii in
715 ts +> List.iter (fun (param,iicomma) ->
716 vk_param bigf param;
717 iif iicomma;
718 )
719
720
721
722(* ------------------------------------------------------------------------ *)
723and vk_asmbody = fun bigf (string_list, colon_list) ->
724 let iif ii = vk_ii bigf ii in
725
726 iif string_list;
727 colon_list +> List.iter (fun (Colon xs, ii) ->
728 iif ii;
729 xs +> List.iter (fun (x,iicomma) ->
730 iif iicomma;
731 (match x with
732 | ColonMisc, ii -> iif ii
733 | ColonExpr e, ii ->
734 vk_expr bigf e;
735 iif ii
736 )
737 ))
738
34e49164 739
485bce71 740(* ------------------------------------------------------------------------ *)
34e49164
C
741let vk_args_splitted = fun bigf args_splitted ->
742 let iif ii = vk_ii bigf ii in
743 args_splitted +> List.iter (function
744 | Left arg -> vk_argument bigf arg
745 | Right ii -> iif ii
746 )
747
748
749let vk_define_params_splitted = fun bigf args_splitted ->
750 let iif ii = vk_ii bigf ii in
751 args_splitted +> List.iter (function
752 | Left (s, iis) -> vk_ii bigf iis
753 | Right ii -> iif ii
754 )
755
756
757
758let vk_params_splitted = fun bigf args_splitted ->
759 let iif ii = vk_ii bigf ii in
760 args_splitted +> List.iter (function
761 | Left arg -> vk_param bigf arg
762 | Right ii -> iif ii
763 )
764
485bce71 765(* ------------------------------------------------------------------------ *)
34e49164
C
766let vk_cst = fun bigf (cst, ii) ->
767 let iif ii = vk_ii bigf ii in
768 iif ii;
769 (match cst with
770 | Left cst -> ()
771 | Right s -> ()
772 )
773
774
775
776
777(*****************************************************************************)
778(* "syntetisized attributes" style *)
779(*****************************************************************************)
485bce71
C
780
781(* TODO port the xxs_s to new cpp construct too *)
782
34e49164
C
783type 'a inout = 'a -> 'a
784
785(* _s for synthetizized attributes
786 *
787 * Note that I don't visit necesserally in the order of the token
788 * found in the original file. So don't assume such hypothesis!
789 *)
790type visitor_c_s = {
791 kexpr_s: (expression inout * visitor_c_s) -> expression inout;
792 kstatement_s: (statement inout * visitor_c_s) -> statement inout;
793 ktype_s: (fullType inout * visitor_c_s) -> fullType inout;
34e49164
C
794
795 kdecl_s: (declaration inout * visitor_c_s) -> declaration inout;
796 kdef_s: (definition inout * visitor_c_s) -> definition inout;
797
485bce71 798 kini_s: (initialiser inout * visitor_c_s) -> initialiser inout;
34e49164 799
485bce71 800 kcppdirective_s: (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
34e49164 801 kdefineval_s: (define_val inout * visitor_c_s) -> define_val inout;
485bce71
C
802 kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
803 kstatementseq_list_s: (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
804
805 knode_s: (F.node inout * visitor_c_s) -> F.node inout;
34e49164 806
485bce71
C
807
808 ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
34e49164
C
809 kinfo_s: (info inout * visitor_c_s) -> info inout;
810 }
811
812let default_visitor_c_s =
813 { kexpr_s = (fun (k,_) e -> k e);
814 kstatement_s = (fun (k,_) st -> k st);
815 ktype_s = (fun (k,_) t -> k t);
816 kdecl_s = (fun (k,_) d -> k d);
817 kdef_s = (fun (k,_) d -> k d);
818 kini_s = (fun (k,_) d -> k d);
819 ktoplevel_s = (fun (k,_) p -> k p);
820 knode_s = (fun (k,_) n -> k n);
821 kinfo_s = (fun (k,_) i -> k i);
822 kdefineval_s = (fun (k,_) x -> k x);
485bce71
C
823 kstatementseq_s = (fun (k,_) x -> k x);
824 kstatementseq_list_s = (fun (k,_) x -> k x);
825 kcppdirective_s = (fun (k,_) x -> k x);
34e49164
C
826 }
827
828let rec vk_expr_s = fun bigf expr ->
829 let iif ii = vk_ii_s bigf ii in
830 let rec exprf e = bigf.kexpr_s (k, bigf) e
831 and k e =
832 let ((unwrap_e, typ), ii) = e in
833 (* don't analyse optional type
834 * old: typ +> map_option (vk_type_s bigf) in
835 *)
836 let typ' = typ in
837 let e' =
838 match unwrap_e with
839 | Ident (s) -> Ident (s)
840 | Constant (c) -> Constant (c)
841 | FunCall (e, es) ->
842 FunCall (exprf e,
843 es +> List.map (fun (e,ii) ->
844 vk_argument_s bigf e, iif ii
845 ))
846
847 | CondExpr (e1, e2, e3) -> CondExpr (exprf e1, fmap exprf e2, exprf e3)
848 | Sequence (e1, e2) -> Sequence (exprf e1, exprf e2)
849 | Assignment (e1, op, e2) -> Assignment (exprf e1, op, exprf e2)
850
851 | Postfix (e, op) -> Postfix (exprf e, op)
852 | Infix (e, op) -> Infix (exprf e, op)
853 | Unary (e, op) -> Unary (exprf e, op)
854 | Binary (e1, op, e2) -> Binary (exprf e1, op, exprf e2)
855
856 | ArrayAccess (e1, e2) -> ArrayAccess (exprf e1, exprf e2)
857 | RecordAccess (e, s) -> RecordAccess (exprf e, s)
858 | RecordPtAccess (e, s) -> RecordPtAccess (exprf e, s)
859
860 | SizeOfExpr (e) -> SizeOfExpr (exprf e)
861 | SizeOfType (t) -> SizeOfType (vk_type_s bigf t)
862 | Cast (t, e) -> Cast (vk_type_s bigf t, exprf e)
863
864 | StatementExpr (statxs, is) ->
865 StatementExpr (
485bce71 866 vk_statement_sequencable_list_s bigf statxs,
34e49164
C
867 iif is)
868 | Constructor (t, initxs) ->
869 Constructor
870 (vk_type_s bigf t,
871 (initxs +> List.map (fun (ini, ii) ->
872 vk_ini_s bigf ini, vk_ii_s bigf ii)
873 ))
874
875 | ParenExpr (e) -> ParenExpr (exprf e)
876
877 in
878 (e', typ'), (iif ii)
879 in exprf expr
880
881and vk_argument_s bigf argument =
882 let iif ii = vk_ii_s bigf ii in
883 let rec do_action = function
884 | (ActMisc ii) -> ActMisc (iif ii)
885 in
886 (match argument with
887 | Left e -> Left (vk_expr_s bigf e)
888 | Right (ArgType param) -> Right (ArgType (vk_param_s bigf param))
889 | Right (ArgAction action) -> Right (ArgAction (do_action action))
890 )
891
892
893
894
895
896
897and vk_statement_s = fun bigf st ->
898 let rec statf st = bigf.kstatement_s (k, bigf) st
899 and k st =
900 let (unwrap_st, ii) = st in
901 let st' =
902 match unwrap_st with
903 | Labeled (Label (s, st)) ->
904 Labeled (Label (s, statf st))
905 | Labeled (Case (e, st)) ->
906 Labeled (Case ((vk_expr_s bigf) e , statf st))
907 | Labeled (CaseRange (e, e2, st)) ->
908 Labeled (CaseRange ((vk_expr_s bigf) e,
909 (vk_expr_s bigf) e2,
910 statf st))
911 | Labeled (Default st) -> Labeled (Default (statf st))
912 | Compound statxs ->
485bce71 913 Compound (vk_statement_sequencable_list_s bigf statxs)
34e49164
C
914 | ExprStatement (None) -> ExprStatement (None)
915 | ExprStatement (Some e) -> ExprStatement (Some ((vk_expr_s bigf) e))
916 | Selection (If (e, st1, st2)) ->
917 Selection (If ((vk_expr_s bigf) e, statf st1, statf st2))
34e49164
C
918 | Selection (Switch (e, st)) ->
919 Selection (Switch ((vk_expr_s bigf) e, statf st))
920 | Iteration (While (e, st)) ->
921 Iteration (While ((vk_expr_s bigf) e, statf st))
922 | Iteration (DoWhile (st, e)) ->
923 Iteration (DoWhile (statf st, (vk_expr_s bigf) e))
924 | Iteration (For ((e1opt,i1), (e2opt,i2), (e3opt,i3), st)) ->
925 let e1opt' = statf (ExprStatement (e1opt),i1) in
926 let e2opt' = statf (ExprStatement (e2opt),i2) in
927 let e3opt' = statf (ExprStatement (e3opt),i3) in
928 (match (e1opt', e2opt', e3opt') with
929 | ((ExprStatement x1,i1), (ExprStatement x2,i2), ((ExprStatement x3,i3))) ->
930 Iteration (For ((x1,i1), (x2,i2), (x3,i3), statf st))
931 | x -> failwith "cant be here if iterator keep ExprStatement as is"
932 )
933
934 | Iteration (MacroIteration (s, es, st)) ->
935 Iteration
936 (MacroIteration
937 (s,
938 es +> List.map (fun (e, ii) ->
939 vk_argument_s bigf e, vk_ii_s bigf ii
940 ),
941 statf st
942 ))
943
944
945 | Jump (Goto s) -> Jump (Goto s)
946 | Jump (((Continue|Break|Return) as x)) -> Jump (x)
947 | Jump (ReturnExpr e) -> Jump (ReturnExpr ((vk_expr_s bigf) e))
948 | Jump (GotoComputed e) -> Jump (GotoComputed (vk_expr_s bigf e));
949
950 | Decl decl -> Decl (vk_decl_s bigf decl)
951 | Asm asmbody -> Asm (vk_asmbody_s bigf asmbody)
952 | NestedFunc def -> NestedFunc (vk_def_s bigf def)
953 | MacroStmt -> MacroStmt
954 in
955 st', vk_ii_s bigf ii
956 in statf st
957
485bce71
C
958
959and vk_statement_sequencable_s = fun bigf stseq ->
960 let f = bigf.kstatementseq_s in
961 let k stseq =
962
963 match stseq with
964 | StmtElem st ->
965 StmtElem (vk_statement_s bigf st)
966 | CppDirectiveStmt directive ->
967 CppDirectiveStmt (vk_cpp_directive_s bigf directive)
968 | IfdefStmt ifdef ->
969 IfdefStmt (vk_ifdef_directive_s bigf ifdef)
970 | IfdefStmt2 (ifdef, xxs) ->
971 let ifdef' = List.map (vk_ifdef_directive_s bigf) ifdef in
972 let xxs' = xxs +> List.map (fun xs ->
973 xs +> List.map (vk_statement_sequencable_s bigf)
974 )
975 in
976 IfdefStmt2(ifdef', xxs')
977 in f (k, bigf) stseq
978
979and vk_statement_sequencable_list_s = fun bigf statxs ->
980 let f = bigf.kstatementseq_list_s in
981 let k xs =
982 xs +> List.map (vk_statement_sequencable_s bigf)
983 in
984 f (k, bigf) statxs
985
986
987
34e49164
C
988and vk_asmbody_s = fun bigf (string_list, colon_list) ->
989 let iif ii = vk_ii_s bigf ii in
990
991 iif string_list,
992 colon_list +> List.map (fun (Colon xs, ii) ->
993 Colon
994 (xs +> List.map (fun (x, iicomma) ->
995 (match x with
996 | ColonMisc, ii -> ColonMisc, iif ii
997 | ColonExpr e, ii -> ColonExpr (vk_expr_s bigf e), iif ii
998 ), iif iicomma
999 )),
1000 iif ii
1001 )
1002
1003
1004
1005
1006and vk_type_s = fun bigf t ->
1007 let rec typef t = bigf.ktype_s (k,bigf) t
1008 and iif ii = vk_ii_s bigf ii
1009 and k t =
1010 let (q, t) = t in
1011 let (unwrap_q, iiq) = q in
1012 let q' = unwrap_q in (* todo? a visitor for qualifier *)
1013 let (unwrap_t, iit) = t in
1014 let t' =
1015 match unwrap_t with
1016 | BaseType x -> BaseType x
1017 | Pointer t -> Pointer (typef t)
1018 | Array (eopt, t) -> Array (fmap (vk_expr_s bigf) eopt, typef t)
1019 | FunctionType (returnt, paramst) ->
1020 FunctionType
1021 (typef returnt,
1022 (match paramst with
1023 | (ts, (b, iihas3dots)) ->
1024 (ts +> List.map (fun (param,iicomma) ->
1025 (vk_param_s bigf param, iif iicomma)),
1026 (b, iif iihas3dots))
1027 ))
1028
1029 | Enum (sopt, enumt) ->
1030 Enum (sopt,
1031 enumt +> List.map (fun (((s, eopt),ii_s_eq), iicomma) ->
1032 ((s, fmap (vk_expr_s bigf) eopt), iif ii_s_eq),
1033 iif iicomma
1034 )
1035 )
1036 | StructUnion (sopt, su, fields) ->
1037 StructUnion (sopt, su, vk_struct_fields_s bigf fields)
1038
1039
1040 | StructUnionName (s, structunion) -> StructUnionName (s, structunion)
1041 | EnumName s -> EnumName s
1042 | TypeName (s, typ) -> TypeName (s, typ)
1043
1044 | ParenType t -> ParenType (typef t)
1045 | TypeOfExpr e -> TypeOfExpr (vk_expr_s bigf e)
1046 | TypeOfType t -> TypeOfType (typef t)
1047 in
1048 (q', iif iiq),
1049 (t', iif iit)
1050
1051
1052 in typef t
1053
485bce71
C
1054and vk_attribute_s = fun bigf attr ->
1055 let iif ii = vk_ii_s bigf ii in
1056 match attr with
1057 | Attribute s, ii ->
1058 Attribute s, iif ii
1059
1060
1061
34e49164
C
1062and vk_decl_s = fun bigf d ->
1063 let f = bigf.kdecl_s in
1064 let iif ii = vk_ii_s bigf ii in
1065 let rec k decl =
1066 match decl with
1067 | DeclList (xs, ii) ->
1068 DeclList (List.map aux xs, iif ii)
1069 | MacroDecl ((s, args),ii) ->
1070 MacroDecl
1071 ((s,
1072 args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii)
1073 ),
1074 iif ii)
1075
1076
485bce71
C
1077 and aux ({v_namei = var; v_type = t;
1078 v_storage = sto; v_local= local; v_attr = attrs}, iicomma) =
1079 {v_namei =
1080 (var +> map_option (fun ((s, ini), ii_s_ini) ->
34e49164
C
1081 (s, ini +> map_option (fun init -> vk_ini_s bigf init)),
1082 iif ii_s_ini
485bce71
C
1083 )
1084 );
1085 v_type = vk_type_s bigf t;
1086 v_storage = sto;
1087 v_local = local;
1088 v_attr = attrs +> List.map (vk_attribute_s bigf);
1089 },
1090 iif iicomma
34e49164
C
1091
1092 in f (k, bigf) d
1093
1094and vk_ini_s = fun bigf ini ->
1095 let rec inif ini = bigf.kini_s (k,bigf) ini
1096 and k ini =
1097 let (unwrap_ini, ii) = ini in
1098 let ini' =
1099 match unwrap_ini with
1100 | InitExpr e -> InitExpr (vk_expr_s bigf e)
1101 | InitList initxs ->
1102 InitList (initxs +> List.map (fun (ini, ii) ->
1103 inif ini, vk_ii_s bigf ii)
1104 )
1105
1106
1107 | InitDesignators (xs, e) ->
1108 InitDesignators
1109 (xs +> List.map (vk_designator_s bigf),
1110 inif e
1111 )
1112
1113 | InitFieldOld (s, e) -> InitFieldOld (s, inif e)
1114 | InitIndexOld (e1, e) -> InitIndexOld (vk_expr_s bigf e1, inif e)
1115
485bce71 1116
34e49164
C
1117 in ini', vk_ii_s bigf ii
1118 in inif ini
1119
1120
1121and vk_designator_s = fun bigf design ->
1122 let iif ii = vk_ii_s bigf ii in
1123 let (designator, ii) = design in
1124 (match designator with
1125 | DesignatorField s -> DesignatorField s
1126 | DesignatorIndex e -> DesignatorIndex (vk_expr_s bigf e)
1127 | DesignatorRange (e1, e2) ->
1128 DesignatorRange (vk_expr_s bigf e1, vk_expr_s bigf e2)
1129 ), iif ii
1130
1131
1132
1133
485bce71
C
1134and vk_struct_fieldkinds_s = fun bigf onefield_multivars ->
1135 let iif ii = vk_ii_s bigf ii in
1136
1137 onefield_multivars +> List.map (fun (field, iicomma) ->
1138 (match field with
1139 | Simple (s, t), iis -> Simple (s, vk_type_s bigf t), iif iis
1140 | BitField (sopt, t, expr), iis ->
1141 BitField (sopt, vk_type_s bigf t, vk_expr_s bigf expr),
1142 iif iis
1143 ), iif iicomma
1144 )
1145
34e49164
C
1146and vk_struct_fields_s = fun bigf fields ->
1147
1148 let iif ii = vk_ii_s bigf ii in
1149
1150 fields +> List.map (fun (xfield, iiptvirg) ->
1151
1152 (match xfield with
485bce71
C
1153 | (DeclarationField (FieldDeclList (onefield_multivars, iiptvirg))) ->
1154 DeclarationField
1155 (FieldDeclList
1156 (vk_struct_fieldkinds_s bigf onefield_multivars, iif iiptvirg))
34e49164 1157 | EmptyField -> EmptyField
485bce71
C
1158 | MacroStructDeclTodo ->
1159 pr2 "MacroStructDeclTodo";
1160 MacroStructDeclTodo
1161
1162 | CppDirectiveStruct directive ->
1163 CppDirectiveStruct (vk_cpp_directive_s bigf directive)
1164 | IfdefStruct ifdef ->
1165 IfdefStruct (vk_ifdef_directive_s bigf ifdef)
1166
34e49164
C
1167 ), iif iiptvirg
1168 )
1169
1170
1171and vk_def_s = fun bigf d ->
1172 let f = bigf.kdef_s in
1173 let iif ii = vk_ii_s bigf ii in
1174 let rec k d =
1175 match d with
485bce71
C
1176 | {f_name = s;
1177 f_type = (returnt, (paramst, (b, iib)));
1178 f_storage = sto;
1179 f_body = statxs;
1180 f_attr = attrs;
1181 }, ii
1182 ->
1183 {f_name = s;
1184 f_type =
1185 (vk_type_s bigf returnt,
1186 (paramst +> List.map (fun (param, iicomma) ->
1187 (vk_param_s bigf param, iif iicomma)
1188 ), (b, iif iib)));
1189 f_storage = sto;
1190 f_body =
1191 vk_statement_sequencable_list_s bigf statxs;
1192 f_attr =
1193 attrs +> List.map (vk_attribute_s bigf)
1194 },
34e49164
C
1195 iif ii
1196
1197 in f (k, bigf) d
1198
1199and vk_toplevel_s = fun bigf p ->
1200 let f = bigf.ktoplevel_s in
1201 let iif ii = vk_ii_s bigf ii in
1202 let rec k p =
1203 match p with
1204 | Declaration decl -> Declaration (vk_decl_s bigf decl)
1205 | Definition def -> Definition (vk_def_s bigf def)
1206 | EmptyDef ii -> EmptyDef (iif ii)
1207 | MacroTop (s, xs, ii) ->
1208 MacroTop
1209 (s,
1210 xs +> List.map (fun (elem, iicomma) ->
1211 vk_argument_s bigf elem, iif iicomma
1212 ),
1213 iif ii
1214 )
485bce71
C
1215 | CppTop top -> CppTop (vk_cpp_directive_s bigf top)
1216 | IfdefTop ifdefdir -> IfdefTop (vk_ifdef_directive_s bigf ifdefdir)
34e49164
C
1217
1218 | NotParsedCorrectly ii -> NotParsedCorrectly (iif ii)
1219 | FinalDef info -> FinalDef (vk_info_s bigf info)
1220 in f (k, bigf) p
1221
485bce71
C
1222and vk_program_s = fun bigf xs ->
1223 xs +> List.map (vk_toplevel_s bigf)
1224
1225
1226and vk_cpp_directive_s = fun bigf top ->
1227 let iif ii = vk_ii_s bigf ii in
1228 let f = bigf.kcppdirective_s in
1229 let rec k top =
1230 match top with
1231 (* go inside ? *)
1232 | Include {i_include = (s, ii);
1233 i_rel_pos = h_rel_pos;
1234 i_is_in_ifdef = b;
1235 i_content = copt;
1236 }
1237 -> Include {i_include = (s, iif ii);
1238 i_rel_pos = h_rel_pos;
1239 i_is_in_ifdef = b;
1240 i_content = copt +> Common.map_option (fun (file, asts) ->
1241 file, vk_program_s bigf asts
1242 );
1243 }
1244 | Define ((s,ii), (defkind, defval)) ->
1245 Define ((s, iif ii),
1246 (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
1247 | Undef (s, ii) -> Undef (s, iif ii)
1248 | PragmaAndCo (ii) -> PragmaAndCo (iif ii)
1249
1250 in f (k, bigf) top
1251
1252and vk_ifdef_directive_s = fun bigf ifdef ->
1253 let iif ii = vk_ii_s bigf ii in
1254 match ifdef with
1255 | IfdefDirective (ifkind, ii) -> IfdefDirective (ifkind, iif ii)
1256
1257
1258
34e49164
C
1259and vk_define_kind_s = fun bigf defkind ->
1260 match defkind with
1261 | DefineVar -> DefineVar
1262 | DefineFunc (params, ii) ->
1263 DefineFunc
1264 (params +> List.map (fun ((s,iis),iicomma) ->
1265 ((s, vk_ii_s bigf iis), vk_ii_s bigf iicomma)
1266 ),
1267 vk_ii_s bigf ii
1268 )
1269
1270
1271and vk_define_val_s = fun bigf x ->
1272 let f = bigf.kdefineval_s in
1273 let iif ii = vk_ii_s bigf ii in
1274 let rec k x =
1275 match x with
1276 | DefineExpr e -> DefineExpr (vk_expr_s bigf e)
1277 | DefineStmt st -> DefineStmt (vk_statement_s bigf st)
485bce71
C
1278 | DefineDoWhileZero ((st,e),ii) ->
1279 let st' = vk_statement_s bigf st in
1280 let e' = vk_expr_s bigf e in
1281 DefineDoWhileZero ((st',e'), iif ii)
34e49164
C
1282 | DefineFunction def -> DefineFunction (vk_def_s bigf def)
1283 | DefineType ty -> DefineType (vk_type_s bigf ty)
1284 | DefineText (s, ii) -> DefineText (s, iif ii)
1285 | DefineEmpty -> DefineEmpty
485bce71
C
1286 | DefineInit ini -> DefineInit (vk_ini_s bigf ini)
1287
1288 | DefineTodo ->
1289 pr2 "DefineTodo";
1290 DefineTodo
34e49164
C
1291 in
1292 f (k, bigf) x
1293
1294
1295and vk_info_s = fun bigf info ->
1296 let rec infof ii = bigf.kinfo_s (k, bigf) ii
1297 and k i = i
1298 in
1299 infof info
1300
1301and vk_ii_s = fun bigf ii ->
1302 List.map (vk_info_s bigf) ii
1303
1304(* ------------------------------------------------------------------------ *)
1305and vk_node_s = fun bigf node ->
1306 let iif ii = vk_ii_s bigf ii in
1307 let infof info = vk_info_s bigf info in
1308
1309 let rec nodef n = bigf.knode_s (k, bigf) n
1310 and k node =
1311 F.rewrap node (
1312 match F.unwrap node with
485bce71
C
1313 | F.FunHeader ({f_name = idb;
1314 f_type =(rett, (paramst,(isvaargs,iidotsb)));
1315 f_storage = stob;
1316 f_body = body;
1317 f_attr = attrs;
1318 },ii) ->
1319 assert(null body);
1320
34e49164 1321 F.FunHeader
485bce71
C
1322 ({f_name =idb;
1323 f_type =
1324 (vk_type_s bigf rett,
1325 (paramst +> List.map (fun (param, iicomma) ->
1326 (vk_param_s bigf param, iif iicomma)
1327 ), (isvaargs,iif iidotsb)));
1328 f_storage = stob;
1329 f_body = body;
1330 f_attr =
1331 attrs +> List.map (vk_attribute_s bigf)
1332 },
1333 iif ii)
34e49164
C
1334
1335
1336 | F.Decl declb -> F.Decl (vk_decl_s bigf declb)
1337 | F.ExprStatement (st, (eopt, ii)) ->
1338 F.ExprStatement (st, (eopt +> map_option (vk_expr_s bigf), iif ii))
1339
1340 | F.IfHeader (st, (e,ii)) ->
1341 F.IfHeader (st, (vk_expr_s bigf e, iif ii))
1342 | F.SwitchHeader (st, (e,ii)) ->
1343 F.SwitchHeader(st, (vk_expr_s bigf e, iif ii))
1344 | F.WhileHeader (st, (e,ii)) ->
1345 F.WhileHeader (st, (vk_expr_s bigf e, iif ii))
1346 | F.DoWhileTail (e,ii) ->
1347 F.DoWhileTail (vk_expr_s bigf e, iif ii)
1348
1349 | F.ForHeader (st, (((e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) ->
1350 F.ForHeader (st,
1351 (((e1opt +> Common.map_option (vk_expr_s bigf), iif i1),
1352 (e2opt +> Common.map_option (vk_expr_s bigf), iif i2),
1353 (e3opt +> Common.map_option (vk_expr_s bigf), iif i3)),
1354 iif ii))
1355
1356 | F.MacroIterHeader (st, ((s,es), ii)) ->
1357 F.MacroIterHeader
1358 (st,
1359 ((s, es +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii)),
1360 iif ii))
1361
1362
1363 | F.ReturnExpr (st, (e,ii)) ->
1364 F.ReturnExpr (st, (vk_expr_s bigf e, iif ii))
1365
1366 | F.Case (st, (e,ii)) -> F.Case (st, (vk_expr_s bigf e, iif ii))
1367 | F.CaseRange (st, ((e1, e2),ii)) ->
1368 F.CaseRange (st, ((vk_expr_s bigf e1, vk_expr_s bigf e2), iif ii))
1369
1370 | F.CaseNode i -> F.CaseNode i
1371
1372 | F.DefineHeader((s,ii), (defkind)) ->
1373 F.DefineHeader ((s, iif ii), (vk_define_kind_s bigf defkind))
1374
1375 | F.DefineExpr e -> F.DefineExpr (vk_expr_s bigf e)
1376 | F.DefineType ft -> F.DefineType (vk_type_s bigf ft)
1377 | F.DefineDoWhileZeroHeader ((),ii) ->
1378 F.DefineDoWhileZeroHeader ((),iif ii)
485bce71
C
1379 | F.DefineTodo -> F.DefineTodo
1380
1381 | F.Include {i_include = (s, ii);
1382 i_rel_pos = h_rel_pos;
1383 i_is_in_ifdef = b;
1384 i_content = copt;
1385 }
1386 ->
1387 assert (copt = None);
1388 F.Include {i_include = (s, iif ii);
1389 i_rel_pos = h_rel_pos;
1390 i_is_in_ifdef = b;
1391 i_content = copt;
1392 }
34e49164 1393
34e49164
C
1394 | F.MacroTop (s, args, ii) ->
1395 F.MacroTop
1396 (s,
1397 args +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii),
1398 iif ii)
1399
1400
1401 | F.MacroStmt (st, ((),ii)) -> F.MacroStmt (st, ((),iif ii))
1402 | F.Asm (st, (body,ii)) -> F.Asm (st, (vk_asmbody_s bigf body,iif ii))
1403
1404 | F.Break (st,((),ii)) -> F.Break (st,((),iif ii))
1405 | F.Continue (st,((),ii)) -> F.Continue (st,((),iif ii))
1406 | F.Default (st,((),ii)) -> F.Default (st,((),iif ii))
1407 | F.Return (st,((),ii)) -> F.Return (st,((),iif ii))
1408 | F.Goto (st, (s,ii)) -> F.Goto (st, (s,iif ii))
1409 | F.Label (st, (s,ii)) -> F.Label (st, (s,iif ii))
1410 | F.EndStatement iopt -> F.EndStatement (map_option infof iopt)
1411 | F.DoHeader (st, info) -> F.DoHeader (st, infof info)
1412 | F.Else info -> F.Else (infof info)
1413 | F.SeqEnd (i, info) -> F.SeqEnd (i, infof info)
1414 | F.SeqStart (st, i, info) -> F.SeqStart (st, i, infof info)
1415
485bce71
C
1416 | F.IfdefHeader (info) -> F.IfdefHeader (vk_ifdef_directive_s bigf info)
1417 | F.IfdefElse (info) -> F.IfdefElse (vk_ifdef_directive_s bigf info)
1418 | F.IfdefEndif (info) -> F.IfdefEndif (vk_ifdef_directive_s bigf info)
1419
34e49164
C
1420 | (
1421 (
1422 F.TopNode|F.EndNode|
1423 F.ErrorExit|F.Exit|F.Enter|
1424 F.FallThroughNode|F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
1425 F.Fake
1426 ) as x) -> x
1427
1428
1429 )
1430 in
1431 nodef node
1432
1433(* ------------------------------------------------------------------------ *)
1434and vk_param_s = fun bigf ((b, s, t), ii_b_s) ->
1435 let iif ii = vk_ii_s bigf ii in
1436 ((b, s, vk_type_s bigf t), iif ii_b_s)
1437
1438let vk_args_splitted_s = fun bigf args_splitted ->
1439 let iif ii = vk_ii_s bigf ii in
1440 args_splitted +> List.map (function
1441 | Left arg -> Left (vk_argument_s bigf arg)
1442 | Right ii -> Right (iif ii)
1443 )
1444
1445let vk_arguments_s = fun bigf args ->
1446 let iif ii = vk_ii_s bigf ii in
1447 args +> List.map (fun (e, ii) -> vk_argument_s bigf e, iif ii)
1448
1449
1450let vk_params_splitted_s = fun bigf args_splitted ->
1451 let iif ii = vk_ii_s bigf ii in
1452 args_splitted +> List.map (function
1453 | Left arg -> Left (vk_param_s bigf arg)
1454 | Right ii -> Right (iif ii)
1455 )
1456
1457let vk_params_s = fun bigf args ->
1458 let iif ii = vk_ii_s bigf ii in
1459 args +> List.map (fun (p,ii) -> vk_param_s bigf p, iif ii)
1460
1461let vk_define_params_splitted_s = fun bigf args_splitted ->
1462 let iif ii = vk_ii_s bigf ii in
1463 args_splitted +> List.map (function
1464 | Left (s, iis) -> Left (s, vk_ii_s bigf iis)
1465 | Right ii -> Right (iif ii)
1466 )
1467
1468let vk_cst_s = fun bigf (cst, ii) ->
1469 let iif ii = vk_ii_s bigf ii in
1470 (match cst with
1471 | Left cst -> Left cst
1472 | Right s -> Right s
1473 ), iif ii