3 * Copyright (C) 2007, 2008, 2009 Ecole des Mines de Nantes
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License (GPL)
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * file license.txt for more details.
16 (*****************************************************************************)
18 (*****************************************************************************)
20 (* todo?: al_expr doit enlever les infos de type ? et doit remettre en
24 (* drop all info information *)
26 let strip_info_visitor _
=
27 { Visitor_c.default_visitor_c_s
with
29 (* traversal should be deterministic... *)
32 function i
-> ctr := !ctr + 1; Ast_c.al_info_cpp
!ctr i
));
34 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
35 let (e'
, ty
),ii'
= k e
in
36 (e'
, Ast_c.noType
()(*ref !ty*)), ii'
(* keep type - jll *)
40 Visitor_c.ktype_s = (fun (k,_) ft ->
42 match Ast_c.unwrap_typeC ft' with
43 | Ast_c.TypeName (s,_typ) ->
44 Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft'
52 let al_expr x
= Visitor_c.vk_expr_s
(strip_info_visitor()) x
53 let al_statement x
= Visitor_c.vk_statement_s
(strip_info_visitor()) x
54 let al_type x
= Visitor_c.vk_type_s
(strip_info_visitor()) x
55 let al_init x
= Visitor_c.vk_ini_s
(strip_info_visitor()) x
56 let al_param x
= Visitor_c.vk_param_s
(strip_info_visitor()) x
57 let al_params x
= Visitor_c.vk_params_s
(strip_info_visitor()) x
58 let al_arguments x
= Visitor_c.vk_arguments_s
(strip_info_visitor()) x
59 let al_fields x
= Visitor_c.vk_struct_fields_s
(strip_info_visitor()) x
61 let al_node x
= Visitor_c.vk_node_s
(strip_info_visitor()) x
63 let al_program x
= List.map
(Visitor_c.vk_toplevel_s
(strip_info_visitor())) x
64 let al_ii x
= Visitor_c.vk_ii_s
(strip_info_visitor()) x
71 let semi_strip_info_visitor = (* keep position information *)
72 { Visitor_c.default_visitor_c_s
with
73 Visitor_c.kinfo_s
= (fun (k
,_
) i
-> Ast_c.semi_al_info_cpp i
);
75 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
76 let (e'
, ty
),ii'
= k e
in
77 (e'
, Ast_c.noType
()(*ref !ty*)), ii'
(* keep type - jll *)
82 let semi_al_expr = Visitor_c.vk_expr_s
semi_strip_info_visitor
83 let semi_al_statement = Visitor_c.vk_statement_s
semi_strip_info_visitor
84 let semi_al_type = Visitor_c.vk_type_s
semi_strip_info_visitor
85 let semi_al_init = Visitor_c.vk_ini_s
semi_strip_info_visitor
86 let semi_al_param = Visitor_c.vk_param_s
semi_strip_info_visitor
87 let semi_al_params = Visitor_c.vk_params_s
semi_strip_info_visitor
88 let semi_al_arguments = Visitor_c.vk_arguments_s
semi_strip_info_visitor
91 List.map
(Visitor_c.vk_toplevel_s
semi_strip_info_visitor)
96 (* really strip, do not keep position nor anything specificities, true
98 let real_strip_info_visitor _
=
99 { Visitor_c.default_visitor_c_s
with
100 Visitor_c.kinfo_s
= (fun (k
,_
) i
->
101 Ast_c.real_al_info_cpp i
104 Visitor_c.kexpr_s
= (fun (k
,_
) e
->
105 let (e'
, ty
),ii'
= k e
in
106 (e'
, Ast_c.noType
()), ii'
110 Visitor_c.ktype_s = (fun (k,_) ft ->
112 match Ast_c.unwrap_typeC ft' with
113 | Ast_c.TypeName (s,_typ) ->
114 Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft'
122 let real_al_expr x
= Visitor_c.vk_expr_s
(real_strip_info_visitor()) x
123 let real_al_node x
= Visitor_c.vk_node_s
(real_strip_info_visitor()) x
124 let real_al_type x
= Visitor_c.vk_type_s
(real_strip_info_visitor()) x
127 (*****************************************************************************)
129 (*****************************************************************************)
131 let extract_info_visitor recursor x
=
132 let globals = ref [] in
135 Visitor_c.default_visitor_c
with
136 Visitor_c.kinfo
= (fun (k
, _
) i
-> Common.push2 i
globals)
143 let ii_of_decl = extract_info_visitor Visitor_c.vk_decl
144 let ii_of_node = extract_info_visitor Visitor_c.vk_node
145 let ii_of_expr = extract_info_visitor Visitor_c.vk_expr
146 let ii_of_stmt = extract_info_visitor Visitor_c.vk_statement
147 let ii_of_args = extract_info_visitor Visitor_c.vk_args_splitted
148 let ii_of_type = extract_info_visitor Visitor_c.vk_type
149 let ii_of_ini = extract_info_visitor Visitor_c.vk_ini
150 let ii_of_param = extract_info_visitor Visitor_c.vk_param
151 let ii_of_params = extract_info_visitor Visitor_c.vk_params_splitted
152 let ii_of_struct_fields = extract_info_visitor Visitor_c.vk_struct_fields
153 (*let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field*)
154 let ii_of_struct_fieldkinds = extract_info_visitor Visitor_c.vk_struct_fieldkinds
155 let ii_of_cst = extract_info_visitor Visitor_c.vk_cst
156 let ii_of_define_params =
157 extract_info_visitor Visitor_c.vk_define_params_splitted
158 let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel
160 (*****************************************************************************)
162 (*****************************************************************************)
163 let max_min_ii_by_pos xs
=
165 | [] -> failwith
"empty list, max_min_ii_by_pos"
168 let pos_leq p1 p2
= (Ast_c.compare_pos p1 p2
) =|= (-1) in
169 xs
+> List.fold_left
(fun (maxii
,minii
) e
->
170 let maxii'
= if pos_leq maxii e
then e
else maxii in
171 let minii'
= if pos_leq e
minii then e
else minii in
175 let info_to_fixpos ii
=
176 match Ast_c.pinfo_of_info ii
with
177 Ast_c.OriginTok pi
-> Ast_cocci.Real pi
.Common.charpos
178 | Ast_c.ExpandedTok
(_
,(pi
,offset
)) ->
179 Ast_cocci.Virt
(pi
.Common.charpos
,offset
)
180 | Ast_c.FakeTok
(_
,(pi
,offset
)) ->
181 Ast_cocci.Virt
(pi
.Common.charpos
,offset
)
182 | Ast_c.AbstractLineTok pi
-> failwith
"unexpected abstract"
184 let max_min_by_pos xs
=
185 let (i1
, i2
) = max_min_ii_by_pos xs
in
186 (info_to_fixpos i1
, info_to_fixpos i2
)
188 let lin_col_by_pos xs
=
189 (* put min before max; no idea why they are backwards above *)
190 let (i2
, i1
) = max_min_ii_by_pos xs
in
191 let posf x
= Ast_c.col_of_info x
in
192 let mposf x
= Ast_c.col_of_info x
+ String.length
(Ast_c.str_of_info x
) in
193 (Ast_c.file_of_info i1
,!Flag.current_element
,
194 (Ast_c.line_of_info i1
, posf i1
), (Ast_c.line_of_info i2
, mposf i2
))
200 let min_pinfo_of_node node
=
201 let ii = ii_of_node node
in
202 let (maxii, minii) = max_min_ii_by_pos ii in
203 Ast_c.parse_info_of_info
minii
206 let (range_of_origin_ii
: Ast_c.info list
-> (int * int) option) =
208 let ii = List.filter
Ast_c.is_origintok
ii in
210 let (max
, min
) = max_min_ii_by_pos ii in
211 assert(Ast_c.is_origintok max
);
212 assert(Ast_c.is_origintok min
);
213 let strmax = Ast_c.str_of_info max
in
215 (Ast_c.pos_of_info min
, Ast_c.pos_of_info max
+ String.length
strmax)
220 (*****************************************************************************)
222 (*****************************************************************************)
224 let names_of_parameters_in_def def
=
225 match def
.Ast_c.f_old_c_style
with
227 pr2_once
"names_of_parameters_in_def: f_old_c_style not handled";
230 let ftyp = def
.Ast_c.f_type
in
231 let (ret
, (params
, bwrap
)) = ftyp in
232 params
+> Common.map_filter
(fun (param
,ii) ->
233 Ast_c.name_of_parameter param
236 let names_of_parameters_in_macro xs
=
237 xs
+> List.map
(fun (xx
, ii) ->