Commit | Line | Data |
---|---|---|
0708f913 C |
1 | (* Yoann Padioleau |
2 | * | |
3 | * Copyright (C) 2007, 2008, 2009 Ecole des Mines de Nantes | |
34e49164 C |
4 | * |
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. | |
8 | * | |
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. | |
13 | *) | |
14 | open Common | |
15 | ||
708f4980 C |
16 | (*****************************************************************************) |
17 | (* Wrappers *) | |
18 | (*****************************************************************************) | |
19 | let pr2, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing | |
20 | ||
34e49164 C |
21 | (*****************************************************************************) |
22 | (* Abstract line *) | |
23 | (*****************************************************************************) | |
24 | ||
25 | (* todo?: al_expr doit enlever les infos de type ? et doit remettre en | |
26 | * emptyAnnot ? | |
27 | *) | |
28 | ||
29 | (* drop all info information *) | |
30 | ||
31 | let strip_info_visitor _ = | |
32 | { Visitor_c.default_visitor_c_s with | |
33 | Visitor_c.kinfo_s = | |
34 | (* traversal should be deterministic... *) | |
35 | (let ctr = ref 0 in | |
36 | (function (k,_) -> | |
b1b2de81 | 37 | function i -> ctr := !ctr + 1; Ast_c.al_info_cpp !ctr i)); |
34e49164 C |
38 | |
39 | Visitor_c.kexpr_s = (fun (k,_) e -> | |
708f4980 | 40 | let (e', ty), ii' = k e in |
34e49164 C |
41 | (e', Ast_c.noType()(*ref !ty*)), ii' (* keep type - jll *) |
42 | ); | |
43 | ||
44 | (* | |
45 | Visitor_c.ktype_s = (fun (k,_) ft -> | |
46 | let ft' = k ft in | |
47 | match Ast_c.unwrap_typeC ft' with | |
48 | | Ast_c.TypeName (s,_typ) -> | |
49 | Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft' | |
50 | | _ -> ft' | |
51 | ||
52 | ); | |
53 | *) | |
54 | ||
55 | } | |
56 | ||
57 | let al_expr x = Visitor_c.vk_expr_s (strip_info_visitor()) x | |
58 | let al_statement x = Visitor_c.vk_statement_s (strip_info_visitor()) x | |
59 | let al_type x = Visitor_c.vk_type_s (strip_info_visitor()) x | |
113803cf | 60 | let al_init x = Visitor_c.vk_ini_s (strip_info_visitor()) x |
34e49164 C |
61 | let al_param x = Visitor_c.vk_param_s (strip_info_visitor()) x |
62 | let al_params x = Visitor_c.vk_params_s (strip_info_visitor()) x | |
63 | let al_arguments x = Visitor_c.vk_arguments_s (strip_info_visitor()) x | |
91eba41f C |
64 | let al_fields x = Visitor_c.vk_struct_fields_s (strip_info_visitor()) x |
65 | ||
66 | let al_node x = Visitor_c.vk_node_s (strip_info_visitor()) x | |
34e49164 C |
67 | |
68 | let al_program x = List.map (Visitor_c.vk_toplevel_s (strip_info_visitor())) x | |
91eba41f C |
69 | let al_ii x = Visitor_c.vk_ii_s (strip_info_visitor()) x |
70 | ||
71 | ||
72 | ||
73 | ||
74 | ||
34e49164 C |
75 | |
76 | let semi_strip_info_visitor = (* keep position information *) | |
77 | { Visitor_c.default_visitor_c_s with | |
b1b2de81 | 78 | Visitor_c.kinfo_s = (fun (k,_) i -> Ast_c.semi_al_info_cpp i); |
34e49164 C |
79 | |
80 | Visitor_c.kexpr_s = (fun (k,_) e -> | |
81 | let (e', ty),ii' = k e in | |
82 | (e', Ast_c.noType()(*ref !ty*)), ii' (* keep type - jll *) | |
83 | ); | |
84 | ||
85 | } | |
86 | ||
87 | let semi_al_expr = Visitor_c.vk_expr_s semi_strip_info_visitor | |
88 | let semi_al_statement = Visitor_c.vk_statement_s semi_strip_info_visitor | |
89 | let semi_al_type = Visitor_c.vk_type_s semi_strip_info_visitor | |
113803cf | 90 | let semi_al_init = Visitor_c.vk_ini_s semi_strip_info_visitor |
34e49164 C |
91 | let semi_al_param = Visitor_c.vk_param_s semi_strip_info_visitor |
92 | let semi_al_params = Visitor_c.vk_params_s semi_strip_info_visitor | |
93 | let semi_al_arguments = Visitor_c.vk_arguments_s semi_strip_info_visitor | |
94 | ||
b1b2de81 C |
95 | let semi_al_program = |
96 | List.map (Visitor_c.vk_toplevel_s semi_strip_info_visitor) | |
34e49164 | 97 | |
91eba41f C |
98 | |
99 | ||
100 | ||
0708f913 C |
101 | (* really strip, do not keep position nor anything specificities, true |
102 | * abstracted form. *) | |
91eba41f C |
103 | let real_strip_info_visitor _ = |
104 | { Visitor_c.default_visitor_c_s with | |
105 | Visitor_c.kinfo_s = (fun (k,_) i -> | |
b1b2de81 | 106 | Ast_c.real_al_info_cpp i |
91eba41f C |
107 | ); |
108 | ||
109 | Visitor_c.kexpr_s = (fun (k,_) e -> | |
110 | let (e', ty),ii' = k e in | |
111 | (e', Ast_c.noType()), ii' | |
112 | ); | |
113 | ||
114 | (* | |
115 | Visitor_c.ktype_s = (fun (k,_) ft -> | |
116 | let ft' = k ft in | |
117 | match Ast_c.unwrap_typeC ft' with | |
118 | | Ast_c.TypeName (s,_typ) -> | |
119 | Ast_c.TypeName (s, Ast_c.noTypedefDef()) +> Ast_c.rewrap_typeC ft' | |
120 | | _ -> ft' | |
121 | ||
122 | ); | |
123 | *) | |
124 | ||
125 | } | |
126 | ||
127 | let real_al_expr x = Visitor_c.vk_expr_s (real_strip_info_visitor()) x | |
128 | let real_al_node x = Visitor_c.vk_node_s (real_strip_info_visitor()) x | |
129 | let real_al_type x = Visitor_c.vk_type_s (real_strip_info_visitor()) x | |
130 | ||
131 | ||
34e49164 C |
132 | (*****************************************************************************) |
133 | (* Extract infos *) | |
134 | (*****************************************************************************) | |
135 | ||
136 | let extract_info_visitor recursor x = | |
137 | let globals = ref [] in | |
138 | let visitor = | |
139 | { | |
140 | Visitor_c.default_visitor_c with | |
141 | Visitor_c.kinfo = (fun (k, _) i -> Common.push2 i globals) | |
142 | } in | |
143 | begin | |
144 | recursor visitor x; | |
145 | !globals | |
146 | end | |
147 | ||
148 | let ii_of_decl = extract_info_visitor Visitor_c.vk_decl | |
149 | let ii_of_node = extract_info_visitor Visitor_c.vk_node | |
150 | let ii_of_expr = extract_info_visitor Visitor_c.vk_expr | |
151 | let ii_of_stmt = extract_info_visitor Visitor_c.vk_statement | |
152 | let ii_of_args = extract_info_visitor Visitor_c.vk_args_splitted | |
153 | let ii_of_type = extract_info_visitor Visitor_c.vk_type | |
154 | let ii_of_ini = extract_info_visitor Visitor_c.vk_ini | |
155 | let ii_of_param = extract_info_visitor Visitor_c.vk_param | |
156 | let ii_of_params = extract_info_visitor Visitor_c.vk_params_splitted | |
157 | let ii_of_struct_fields = extract_info_visitor Visitor_c.vk_struct_fields | |
485bce71 C |
158 | (*let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field*) |
159 | let ii_of_struct_fieldkinds = extract_info_visitor Visitor_c.vk_struct_fieldkinds | |
34e49164 C |
160 | let ii_of_cst = extract_info_visitor Visitor_c.vk_cst |
161 | let ii_of_define_params = | |
162 | extract_info_visitor Visitor_c.vk_define_params_splitted | |
485bce71 | 163 | let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel |
34e49164 | 164 | |
91eba41f C |
165 | (*****************************************************************************) |
166 | (* Max min, range *) | |
485bce71 | 167 | (*****************************************************************************) |
34e49164 C |
168 | let max_min_ii_by_pos xs = |
169 | match xs with | |
170 | | [] -> failwith "empty list, max_min_ii_by_pos" | |
171 | | [x] -> (x, x) | |
172 | | x::xs -> | |
b1b2de81 | 173 | let pos_leq p1 p2 = (Ast_c.compare_pos p1 p2) =|= (-1) in |
34e49164 C |
174 | xs +> List.fold_left (fun (maxii,minii) e -> |
175 | let maxii' = if pos_leq maxii e then e else maxii in | |
176 | let minii' = if pos_leq e minii then e else minii in | |
177 | maxii', minii' | |
178 | ) (x,x) | |
179 | ||
180 | let info_to_fixpos ii = | |
181 | match Ast_c.pinfo_of_info ii with | |
182 | Ast_c.OriginTok pi -> Ast_cocci.Real pi.Common.charpos | |
183 | | Ast_c.ExpandedTok (_,(pi,offset)) -> | |
184 | Ast_cocci.Virt (pi.Common.charpos,offset) | |
185 | | Ast_c.FakeTok (_,(pi,offset)) -> | |
186 | Ast_cocci.Virt (pi.Common.charpos,offset) | |
187 | | Ast_c.AbstractLineTok pi -> failwith "unexpected abstract" | |
188 | ||
189 | let max_min_by_pos xs = | |
190 | let (i1, i2) = max_min_ii_by_pos xs in | |
191 | (info_to_fixpos i1, info_to_fixpos i2) | |
192 | ||
193 | let lin_col_by_pos xs = | |
194 | (* put min before max; no idea why they are backwards above *) | |
195 | let (i2, i1) = max_min_ii_by_pos xs in | |
196 | let posf x = Ast_c.col_of_info x in | |
197 | let mposf x = Ast_c.col_of_info x + String.length (Ast_c.str_of_info x) in | |
485bce71 | 198 | (Ast_c.file_of_info i1,!Flag.current_element, |
34e49164 C |
199 | (Ast_c.line_of_info i1, posf i1), (Ast_c.line_of_info i2, mposf i2)) |
200 | ||
201 | ||
91eba41f C |
202 | |
203 | ||
204 | ||
205 | let min_pinfo_of_node node = | |
206 | let ii = ii_of_node node in | |
207 | let (maxii, minii) = max_min_ii_by_pos ii in | |
208 | Ast_c.parse_info_of_info minii | |
209 | ||
210 | ||
211 | let (range_of_origin_ii: Ast_c.info list -> (int * int) option) = | |
212 | fun ii -> | |
213 | let ii = List.filter Ast_c.is_origintok ii in | |
214 | try | |
215 | let (max, min) = max_min_ii_by_pos ii in | |
216 | assert(Ast_c.is_origintok max); | |
217 | assert(Ast_c.is_origintok min); | |
218 | let strmax = Ast_c.str_of_info max in | |
219 | Some | |
220 | (Ast_c.pos_of_info min, Ast_c.pos_of_info max + String.length strmax) | |
221 | with _ -> | |
222 | None | |
0708f913 C |
223 | |
224 | ||
225 | (*****************************************************************************) | |
226 | (* Ast getters *) | |
227 | (*****************************************************************************) | |
228 | ||
229 | let names_of_parameters_in_def def = | |
230 | match def.Ast_c.f_old_c_style with | |
231 | | Some _ -> | |
232 | pr2_once "names_of_parameters_in_def: f_old_c_style not handled"; | |
233 | [] | |
234 | | None -> | |
235 | let ftyp = def.Ast_c.f_type in | |
236 | let (ret, (params, bwrap)) = ftyp in | |
237 | params +> Common.map_filter (fun (param,ii) -> | |
238 | Ast_c.name_of_parameter param | |
239 | ) | |
240 | ||
241 | let names_of_parameters_in_macro xs = | |
242 | xs +> List.map (fun (xx, ii) -> | |
243 | let (s, ii2) = xx in | |
244 | s | |
245 | ) | |
708f4980 C |
246 | |
247 | ||
248 | ||
249 | (* only used in ast_to_flow, so move it ? *) | |
250 | let rec stmt_elems_of_sequencable xs = | |
251 | xs +> Common.map (fun x -> | |
252 | match x with | |
253 | | Ast_c.StmtElem e -> [e] | |
254 | | Ast_c.CppDirectiveStmt _ | |
255 | | Ast_c.IfdefStmt _ | |
256 | -> | |
257 | pr2_once ("stmt_elems_of_sequencable: filter a directive"); | |
258 | [] | |
259 | | Ast_c.IfdefStmt2 (_ifdef, xxs) -> | |
260 | pr2 ("stmt_elems_of_sequencable: IfdefStm2 TODO?"); | |
261 | xxs +> List.map (fun xs -> | |
262 | let xs' = stmt_elems_of_sequencable xs in | |
263 | xs' | |
264 | ) +> List.flatten | |
265 | ) +> List.flatten | |
266 | ||
267 | ||
268 |