2 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
3 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
4 * This file is part of Coccinelle.
6 * Coccinelle is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, according to version 2 of the License.
10 * Coccinelle 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 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
18 * The authors reserve the right to distribute this or future versions of
19 * Coccinelle under other licenses.
23 module Ast0
= Ast0_cocci
24 module Ast
= Ast_cocci
25 module V0
= Visitor_ast0
26 module VT0
= Visitor_ast0_types
28 (* find assignments that can match an initialization *)
30 let pure_mcodekind = function
33 (Ast.NOTHING
,_
,_
) -> true
37 let is_simple_assign left op
=
38 (match Ast0.unwrap left
with
39 Ast0.Ident
(_
) | Ast0.MetaExpr
(_
,_
,_
,_
,_
) -> true
42 ((Ast0.unwrap_mcode op
) = Ast.SimpleAssign
)
44 let is_simple_ast_assign left op minus_left
=
45 (match Ast.unwrap left
with
47 | Ast.MetaExpr
(name
,_
,_
,_
,_
,_
) ->
48 (match Ast0.unwrap minus_left
with
49 Ast0.MetaExpr
(name1
,_
,_
,_
,_
) ->
50 Ast.unwrap_mcode name
= Ast0.unwrap_mcode name1
54 ((Ast.unwrap_mcode op
) = Ast.SimpleAssign
)
58 ("the simple assignment expression on line "^
59 (string_of_int
(Ast0.get_line e
))^
60 " contains transformations\n"^
61 "that prevent it from matching a declaration ("^msg^
")\n");
64 let rebuild e1 left right op simple
=
65 Ast0.rewrap e1
(Ast0.Assignment
(left
,op
,right
,simple
))
68 match Ast0.unwrap e1
with
69 Ast0.Assignment
(left
,op
,right
,_
) ->
70 if is_simple_assign left op
73 then rebuild e1 left right op
true
78 ([[Ast.ExpressionTag
(e2
)]],_
) ->
79 (match Ast.unwrap e2
with
80 Ast.Assignment
(left'
,op'
,_
,_
) ->
81 if is_simple_ast_assign left' op' left
82 then rebuild e1 left right op
true
83 else warning e1
"replacement is not simple"
84 | _
-> warning e1
"replacement is not an assignment")
85 | _
-> warning e1
"multiple replacements")
89 (pure_mcodekind (Ast0.get_mcodekind left
)) &&
90 (pure_mcodekind (Ast0.get_mcode_mcodekind op
)) in
92 then warning e1
"not pure"
93 else rebuild e1 left right op
pure)
95 | Ast0.DisjExpr
(lp
,exps
,mids
,rp
) ->
98 (lp
,List.map
(function x
-> exp (Ast0.get_mcodekind x
) x
) exps
,
101 Ast0.rewrap e1
(Ast0.OptExp
(exp (Ast0.get_mcodekind e
) e
))
102 | Ast0.UniqueExp
(e
) ->
103 Ast0.rewrap e1
(Ast0.UniqueExp
(exp (Ast0.get_mcodekind e
) e
))
106 let simple_assignments l
=
107 let statement r k e
=
108 match Ast0.unwrap e
with
109 Ast0.Exp
(e1
) -> Ast0.rewrap e
(Ast0.Exp
(exp (Ast0.get_mcodekind e
) e1
))
113 {V0.rebuilder_functions
with VT0.rebuilder_stmtfn
= statement} in
114 List.map
fn.VT0.rebuilder_rec_top_level l