Coccinelle release-1.0.0-rc11
[bpt/coccinelle.git] / parsing_cocci / safe_for_multi_decls.ml
CommitLineData
f537ebc4 1(*
17ba0788
C
2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
f537ebc4
C
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
9 *
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
13 *
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
24 *)
25
26
690d68d1
C
27(* This phase sets the safe_for_multi_decls field, which is normally false,
28to true for transformations on declarations where the only change is on the
29declared variable. This is the only kind of change on such a declaration
30that can safely be done without splitting the declaration. *)
31
32module Ast = Ast_cocci
33module V = Visitor_ast
34
35let mcode _ (_,_,kind,_) =
36 match kind with
37 Ast.MINUS(_,_,_,_) -> true
38 | Ast.PLUS _ -> failwith "not possible"
39 | Ast.CONTEXT(_,info) -> not (info = Ast.NOTHING)
40
41let contains_modif =
42 let bind x y = x or y in
43 let option_default = false in
44 let do_nothing r k e = k e in
45 let rule_elem r k re =
46 let res = k re in
47 match Ast.unwrap re with
48 Ast.FunHeader(bef,_,fninfo,name,lp,params,rp) ->
8f657093
C
49 bind (mcode r ((),(),bef,[])) res
50 | Ast.Decl(bef,_,decl) -> bind (mcode r ((),(),bef,[])) res
690d68d1
C
51 | _ -> res in
52 let init r k i =
53 let res = k i in
54 match Ast.unwrap i with
55 Ast.StrInitList(allminus,_,_,_,_) -> allminus or res
56 | _ -> res in
57 let recursor =
58 V.combiner bind option_default
59 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
60 do_nothing do_nothing do_nothing do_nothing do_nothing
61 do_nothing do_nothing do_nothing do_nothing init do_nothing
62 do_nothing rule_elem do_nothing do_nothing do_nothing do_nothing in
63 recursor.V.combiner_fullType
64
65let decl r k e =
66 let e = k e in
67 match Ast.unwrap e with
68 Ast.Init(stg,ty,_,_,_,sem)
69 | Ast.UnInit(stg,ty,_,sem) ->
70 let stg_modif =
71 match stg with
72 Some stg -> mcode () stg
73 | None -> false in
74 let ft_modif = contains_modif ty in
75 let sem_modif = mcode () sem in
76 if not(stg_modif or ft_modif or sem_modif)
77 then {e with Ast.safe_for_multi_decls = true}
78 else e
79 | _ -> e
80let mcode e = e
81let donothing r k e = k e
82
83let process =
84 let fn = V.rebuilder
85 mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
86 donothing donothing donothing donothing donothing
87 donothing donothing donothing donothing
88 donothing donothing decl donothing
89 donothing donothing donothing donothing in
90 List.map fn.V.rebuilder_top_level
91
92let safe_for_multi_decls rules =
93 List.map
94 (function (mv,r) ->
95 (mv,
96 match r with
97 Ast.ScriptRule _
98 | Ast.InitialScriptRule _ | Ast.FinalScriptRule _ -> r
99 | Ast.CocciRule (nm, rule_info, r, is_exp,ruletype) ->
100 Ast.CocciRule(nm, rule_info,process r,is_exp,ruletype)))
101 rules