Coccinelle release 1.0.0-rc4
[bpt/coccinelle.git] / parsing_cocci / parse_aux.ml
CommitLineData
f537ebc4
C
1(*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
34e49164
C
25(* exports everything, used only by parser_cocci_menhir.mly *)
26module Ast0 = Ast0_cocci
27module Ast = Ast_cocci
28
29(* types for metavariable tokens *)
30type info = Ast.meta_name * Ast0.pure * Data.clt
8babbc8f
C
31type midinfo =
32 Ast.meta_name * Data.iconstraints * Ast.seed * Ast0.pure * Data.clt
34e49164
C
33type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt
34type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt
35type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt
88e71198 36type list_info = Ast.meta_name * Ast.list_len * Ast0.pure * Data.clt
951c7801 37type typed_expinfo =
34e49164
C
38 Ast.meta_name * Data.econstraints * Ast0.pure *
39 Type_cocci.typeC list option * Data.clt
40type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt
41
34e49164
C
42let get_option fn = function
43 None -> None
44 | Some x -> Some (fn x)
45
46let make_info line logical_line offset col strbef straft =
0708f913
C
47 let new_pos_info =
48 {Ast0.line_start = line; Ast0.line_end = line;
49 Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
708f4980 50 Ast0.column = col; Ast0.offset = offset; } in
0708f913 51 { Ast0.pos_info = new_pos_info;
34e49164
C
52 Ast0.attachable_start = true; Ast0.attachable_end = true;
53 Ast0.mcode_start = []; Ast0.mcode_end = [];
34e49164
C
54 Ast0.strings_before = strbef; Ast0.strings_after = straft; }
55
56let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
57 make_info line logical_line offset col strbef straft
58
59let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) =
60 (arity,line,lline,offset,col,[],straft,pos)
61
62let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
63 (arity,line,lline,offset,col,strbef,[],pos)
64
8f657093
C
65(* used for #define, to put aft on ident/( *)
66let get_aft (arity,line,lline,offset,col,strbef,straft,pos) = straft
67
68let set_aft aft (arity,line,lline,offset,col,strbef,_,pos) =
69 (arity,line,lline,offset,col,strbef,aft,pos)
70
7f004419 71let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) =
8f657093 72 (arity,line,lline,offset,col,strbef,straft,[])
7f004419 73
34e49164
C
74let clt2mcode str = function
75 (Data.MINUS,line,lline,offset,col,strbef,straft,pos) ->
76 (str,Ast0.NONE,make_info line lline offset col strbef straft,
8babbc8f 77 Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)),ref pos,-1)
34e49164
C
78 | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) ->
79 (str,Ast0.OPT,make_info line lline offset col strbef straft,
8babbc8f 80 Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)),ref pos,-1)
34e49164
C
81 | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) ->
82 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
8babbc8f 83 Ast0.MINUS(ref(Ast.NOREPLACEMENT,Ast0.default_token_info)),ref pos,-1)
34e49164 84 | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) ->
951c7801
C
85 (str,Ast0.NONE,make_info line lline offset col strbef straft,
86 Ast0.PLUS(Ast.ONE),ref pos,-1)
87 | (Data.PLUSPLUS,line,lline,offset,col,strbef,straft,pos) ->
88 (str,Ast0.NONE,make_info line lline offset col strbef straft,
89 Ast0.PLUS(Ast.MANY),ref pos,-1)
34e49164
C
90 | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) ->
91 (str,Ast0.NONE,make_info line lline offset col strbef straft,
92 Ast0.CONTEXT(ref(Ast.NOTHING,
93 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 94 ref pos,-1)
34e49164
C
95 | (Data.OPT,line,lline,offset,col,strbef,straft,pos) ->
96 (str,Ast0.OPT,make_info line lline offset col strbef straft,
97 Ast0.CONTEXT(ref(Ast.NOTHING,
98 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 99 ref pos,-1)
34e49164
C
100 | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) ->
101 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
102 Ast0.CONTEXT(ref(Ast.NOTHING,
103 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 104 ref pos,-1)
34e49164
C
105
106let id2name (name, clt) = name
107let id2clt (name, clt) = clt
108let id2mcode (name, clt) = clt2mcode name clt
109
110let mkdots str (dot,whencode) =
111 match str with
112 "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode))
113 | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode))
114 | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode))
115 | _ -> failwith "cannot happen"
116
117let mkedots str (dot,whencode) =
118 match str with
119 "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode))
120 | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode))
121 | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode))
122 | _ -> failwith "cannot happen"
123
124let mkdpdots str dot =
125 match str with
126 "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot))
127 | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot))
128 | _ -> failwith "cannot happen"
129
130let mkidots str (dot,whencode) =
131 match str with
132 "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode))
133 | _ -> failwith "cannot happen"
134
135let mkddots str (dot,whencode) =
136 match (str,whencode) with
137 ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None))
138 | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w))
139 | _ -> failwith "cannot happen"
140
c491d8ee
C
141let mkddots_one str (dot,whencode) =
142 match str with
143 "..." -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, whencode))
144 | _ -> failwith "cannot happen"
145
34e49164
C
146let mkpdots str dot =
147 match str with
148 "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot))
149 | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot))
150 | _ -> failwith "cannot happen"
151
152let arith_op ast_op left op right =
153 Ast0.wrap
154 (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right))
155
156let logic_op ast_op left op right =
157 Ast0.wrap
158 (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right))
159
160let make_cv cv ty =
161 match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty))
162
163let top_dots l =
164 let circle x =
165 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
166 let star x =
167 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
168 if List.exists circle l
169 then Ast0.wrap(Ast0.CIRCLES(l))
170 else
171 if List.exists star l
172 then Ast0.wrap(Ast0.STARS(l))
173 else Ast0.wrap(Ast0.DOTS(l))
174
175(* here the offset is that of the first in the sequence of *s, not that of
176each * individually *)
177let pointerify ty m =
178 List.fold_left
179 (function inner ->
180 function cur ->
181 Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur)))
182 ty m
183
184let ty_pointerify ty m =
185 List.fold_left
186 (function inner -> function cur -> Type_cocci.Pointer(inner))
187 ty m
188
190f1acf
C
189let arrayify ty ar =
190 List.fold_right
191 (function (l,i,r) ->
192 function rest ->
193 Ast0.wrap (Ast0.Array(rest,clt2mcode "[" l,i,clt2mcode "]" r)))
194 ar ty
195
34e49164
C
196(* Left is <=>, Right is =>. Collect <=>s. *)
197(* The parser should have done this, with precedences. But whatever... *)
c3e37e97 198let iso_adjust first_fn fn first rest =
34e49164
C
199 let rec loop = function
200 [] -> [[]]
201 | (Common.Left x)::rest ->
202 (match loop rest with
203 front::after -> (fn x::front)::after
204 | _ -> failwith "not possible")
205 | (Common.Right x)::rest ->
206 (match loop rest with
207 front::after -> []::(fn x::front)::after
208 | _ -> failwith "not possible") in
209 match loop rest with
c3e37e97 210 front::after -> (first_fn first::front)::after
34e49164
C
211 | _ -> failwith "not possible"
212
174d1640
C
213let lookup rule name =
214 try
215 let info = Hashtbl.find Data.all_metadecls rule in
216 List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info
217 with
218 Not_found ->
219 raise
220 (Semantic_cocci.Semantic("bad rule "^rule^" or bad variable "^name))
221
222let check_meta_tyopt type_irrelevant = function
b23ff9c7
C
223 Ast.MetaMetaDecl(Ast.NONE,(rule,name)) ->
224 (match lookup rule name with
225 Ast.MetaMetaDecl(_,_) -> ()
226 | _ ->
227 raise
228 (Semantic_cocci.Semantic
229 ("incompatible inheritance declaration "^name)))
230 | Ast.MetaIdDecl(Ast.NONE,(rule,name)) ->
34e49164
C
231 (match lookup rule name with
232 Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> ()
233 | _ ->
234 raise
235 (Semantic_cocci.Semantic
236 ("incompatible inheritance declaration "^name)))
b1b2de81 237 | Ast.MetaFreshIdDecl((rule,name),seed) ->
34e49164
C
238 raise
239 (Semantic_cocci.Semantic
240 "can't inherit the freshness of an identifier")
241 | Ast.MetaListlenDecl((rule,name)) ->
242 (match lookup rule name with
243 Ast.MetaListlenDecl(_) -> ()
244 | _ ->
245 raise
246 (Semantic_cocci.Semantic
247 ("incompatible inheritance declaration "^name)))
248 | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) ->
249 (match lookup rule name with
250 Ast.MetaTypeDecl(_,_) -> ()
251 | _ ->
252 raise
253 (Semantic_cocci.Semantic
254 ("incompatible inheritance declaration "^name)))
113803cf
C
255 | Ast.MetaInitDecl(Ast.NONE,(rule,name)) ->
256 (match lookup rule name with
257 Ast.MetaInitDecl(_,_) -> ()
258 | _ ->
259 raise
260 (Semantic_cocci.Semantic
261 ("incompatible inheritance declaration "^name)))
8f657093
C
262 | Ast.MetaInitListDecl(Ast.NONE,(rule,name),len_name) ->
263 (match lookup rule name with
264 Ast.MetaInitListDecl(_,_,_) -> ()
265 | _ ->
266 raise
267 (Semantic_cocci.Semantic
268 ("incompatible inheritance declaration "^name)))
34e49164
C
269 | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
270 (match lookup rule name with
271 Ast.MetaParamDecl(_,_) -> ()
272 | _ ->
273 raise
274 (Semantic_cocci.Semantic
275 ("incompatible inheritance declaration "^name)))
276 | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) ->
277 (match lookup rule name with
278 Ast.MetaParamListDecl(_,_,_) -> ()
279 | _ ->
280 raise
281 (Semantic_cocci.Semantic
282 ("incompatible inheritance declaration "^name)))
283 | Ast.MetaErrDecl(Ast.NONE,(rule,name)) ->
284 (match lookup rule name with
285 Ast.MetaErrDecl(_,_) -> ()
286 | _ ->
287 raise
288 (Semantic_cocci.Semantic
289 ("incompatible inheritance declaration "^name)))
290 | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) ->
291 (match lookup rule name with
5636bb2c 292 Ast.MetaExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
293 | _ ->
294 raise
295 (Semantic_cocci.Semantic
296 ("incompatible inheritance declaration "^name)))
297 | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) ->
298 (match lookup rule name with
5636bb2c 299 Ast.MetaIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
300 | _ ->
301 raise
302 (Semantic_cocci.Semantic
303 ("incompatible inheritance declaration "^name)))
304 | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) ->
305 (match lookup rule name with
5636bb2c 306 Ast.MetaLocalIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
307 | _ ->
308 raise
309 (Semantic_cocci.Semantic
310 ("incompatible inheritance declaration "^name)))
311 | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) ->
312 (match lookup rule name with
313 Ast.MetaExpListDecl(_,_,_) -> ()
faf9a90c 314 | Ast.MetaParamListDecl(_,_,_) when not (!Flag.make_hrule = None) -> ()
34e49164
C
315 | _ ->
316 raise
317 (Semantic_cocci.Semantic
318 ("incompatible inheritance declaration "^name)))
319 | Ast.MetaStmDecl(Ast.NONE,(rule,name)) ->
320 (match lookup rule name with
321 Ast.MetaStmDecl(_,_) -> ()
322 | _ ->
323 raise
324 (Semantic_cocci.Semantic
325 ("incompatible inheritance declaration "^name)))
326 | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) ->
327 (match lookup rule name with
328 Ast.MetaStmListDecl(_,_) -> ()
329 | _ ->
330 raise
331 (Semantic_cocci.Semantic
332 ("incompatible inheritance declaration "^name)))
333 | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) ->
334 (match lookup rule name with
335 Ast.MetaFuncDecl(_,_) -> ()
336 | _ ->
337 raise
338 (Semantic_cocci.Semantic
339 ("incompatible inheritance declaration "^name)))
340 | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) ->
341 (match lookup rule name with
342 Ast.MetaLocalFuncDecl(_,_) -> ()
343 | _ ->
344 raise
345 (Semantic_cocci.Semantic
346 ("incompatible inheritance declaration "^name)))
347 | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) ->
348 (match lookup rule name with
5636bb2c 349 Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
350 | _ ->
351 raise
352 (Semantic_cocci.Semantic
353 ("incompatible inheritance declaration "^name)))
354 | Ast.MetaPosDecl(Ast.NONE,(rule,name)) ->
355 (match lookup rule name with
356 Ast.MetaPosDecl(_,_) ->
357 if not (List.mem rule !Data.inheritable_positions)
358 then
359 raise
360 (Semantic_cocci.Semantic
361 ("position cannot be inherited over modifications: "^name))
362 | _ ->
363 raise
364 (Semantic_cocci.Semantic
365 ("incompatible inheritance declaration "^name)))
366 | _ ->
367 raise
368 (Semantic_cocci.Semantic ("arity not allowed on imported declaration"))
369
5636bb2c
C
370let check_meta m = check_meta_tyopt false m
371
372let check_inherited_constraint meta_name fn =
373 match meta_name with
374 (None,_) -> failwith "constraint must be an inherited variable"
375 | (Some rule,name) ->
376 let i = (rule,name) in
377 check_meta_tyopt true (fn i);
378 i
379
34e49164
C
380let create_metadec ar ispure kindfn ids current_rule =
381 List.concat
382 (List.map
383 (function (rule,nm) ->
384 let (rule,checker) =
385 match rule with
386 None -> ((current_rule,nm),function x -> [Common.Left x])
387 | Some rule ->
388 ((rule,nm),
389 function x -> check_meta x; [Common.Right x]) in
390 kindfn ar rule ispure checker)
391 ids)
392
ae4735db
C
393
394let create_metadec_virt ar ispure kindfn ids current_rule =
395 List.concat
396 (List.map
397 (function nm ->
398 let checker = function x -> [Common.Right x] in
399 kindfn ar nm ispure checker !Flag.defined_virtual_env)
400 ids)
401
b1b2de81
C
402let create_fresh_metadec kindfn ids current_rule =
403 List.concat
404 (List.map
405 (function ((rule,nm),seed) ->
406 let (rule,checker) =
407 match rule with
408 None -> ((current_rule,nm),function x -> [Common.Left x])
409 | Some rule ->
410 ((rule,nm),
411 function x -> check_meta x; [Common.Right x]) in
412 kindfn rule checker seed)
413 ids)
414
951c7801 415let create_metadec_with_constraints ar ispure kindfn ids current_rule =
34e49164
C
416 List.concat
417 (List.map
418 (function ((rule,nm),constraints) ->
419 let (rule,checker) =
420 match rule with
951c7801
C
421 None -> ((current_rule,nm),function x -> [Common.Left x])
422 | Some rule ->
423 ((rule,nm),
424 function x -> check_meta x; [Common.Right x]) in
425 kindfn ar rule ispure checker constraints)
34e49164
C
426 ids)
427
428let create_metadec_ty ar ispure kindfn ids current_rule =
429 List.concat
430 (List.map
431 (function ((rule,nm),constraints) ->
432 let (rule,checker) =
433 match rule with
434 None -> ((current_rule,nm),function x -> [Common.Left x])
435 | Some rule ->
436 ((rule,nm),
437 function x -> check_meta x; [Common.Right x]) in
438 kindfn ar rule ispure checker constraints)
439 ids)
440
441let create_len_metadec ar ispure kindfn lenid ids current_rule =
88e71198
C
442 let (lendec,lenname) =
443 match lenid with
444 Common.Left lenid ->
445 let lendec =
446 create_metadec Ast.NONE Ast0.Impure
447 (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name)))
448 [lenid] current_rule in
449 let lenname =
450 match lendec with
451 [Common.Left (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
452 | [Common.Right (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
453 | _ -> failwith "unexpected length declaration" in
454 (lendec,lenname)
455 | Common.Right n -> ([],Ast.CstLen n) in
34e49164
C
456 lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule)
457
458(* ---------------------------------------------------------------------- *)
459
460let str2inc s =
461 let elements = Str.split (Str.regexp "/") s in
462 List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements
463
464(* ---------------------------------------------------------------------- *)
413ffc02
C
465(* declarations and statements *)
466
467let meta_decl name =
468 let (nm,pure,clt) = name in
469 Ast0.wrap(Ast0.MetaDecl(clt2mcode nm clt,pure))
470
471let meta_field name =
472 let (nm,pure,clt) = name in
473 Ast0.wrap(Ast0.MetaField(clt2mcode nm clt,pure))
34e49164 474
190f1acf
C
475let meta_field_list name =
476 let (nm,lenname,pure,clt) = name in
477 let lenname =
478 match lenname with
479 Ast.AnyLen -> Ast0.AnyListLen
480 | Ast.MetaLen nm -> Ast0.MetaListLen(clt2mcode nm clt)
481 | Ast.CstLen n -> Ast0.CstListLen n in
482 Ast0.wrap(Ast0.MetaFieldList(clt2mcode nm clt,lenname,pure))
483
34e49164
C
484let meta_stm name =
485 let (nm,pure,clt) = name in
486 Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure))
487
488let exp_stm exp pv =
489 Ast0.wrap(Ast0.ExprStatement (exp, clt2mcode ";" pv))
490
491let ifthen iff lp tst rp thn =
492 Ast0.wrap(Ast0.IfThen(clt2mcode "if" iff,
493 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
494 (Ast0.default_info(),Ast0.context_befaft())))
495
496let ifthenelse iff lp tst rp thn e els =
497 Ast0.wrap(Ast0.IfThenElse(clt2mcode "if" iff,
498 clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
499 clt2mcode "else" e,els,
500 (Ast0.default_info(),Ast0.context_befaft())))
501
502let forloop fr lp e1 sc1 e2 sc2 e3 rp s =
503 Ast0.wrap(Ast0.For(clt2mcode "for" fr,clt2mcode "(" lp,e1,
504 clt2mcode ";" sc1,e2,
505 clt2mcode ";" sc2,e3,clt2mcode ")" rp,s,
506 (Ast0.default_info(),Ast0.context_befaft())))
507
508let whileloop w lp e rp s =
509 Ast0.wrap(Ast0.While(clt2mcode "while" w,clt2mcode "(" lp,
510 e,clt2mcode ")" rp,s,
511 (Ast0.default_info(),Ast0.context_befaft())))
512
513let doloop d s w lp e rp pv =
514 Ast0.wrap(Ast0.Do(clt2mcode "do" d,s,clt2mcode "while" w,
515 clt2mcode "(" lp,e,clt2mcode ")" rp,
516 clt2mcode ";" pv))
517
518let iterator i lp e rp s =
519 Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s,
520 (Ast0.default_info(),Ast0.context_befaft())))
521
fc1ad971
C
522let switch s lp e rp lb d c rb =
523 let d =
524 List.map
525 (function d ->
526 Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),d)))
527 d in
34e49164
C
528 Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e,
529 clt2mcode ")" rp,clt2mcode "{" lb,
fc1ad971 530 Ast0.wrap(Ast0.DOTS(d)),
34e49164
C
531 Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb))
532
533let ret_exp r e pv =
534 Ast0.wrap(Ast0.ReturnExpr(clt2mcode "return" r,e,clt2mcode ";" pv))
535
536let ret r pv =
537 Ast0.wrap(Ast0.Return(clt2mcode "return" r,clt2mcode ";" pv))
538
539let break b pv =
540 Ast0.wrap(Ast0.Break(clt2mcode "break" b,clt2mcode ";" pv))
541
542let cont c pv =
543 Ast0.wrap(Ast0.Continue(clt2mcode "continue" c,clt2mcode ";" pv))
544
545let label i dd =
546 Ast0.wrap(Ast0.Label(i,clt2mcode ":" dd))
547
548let goto g i pv =
549 Ast0.wrap(Ast0.Goto(clt2mcode "goto" g,i,clt2mcode ";" pv))
550
551let seq lb s rb =
552 Ast0.wrap(Ast0.Seq(clt2mcode "{" lb,s,clt2mcode "}" rb))
553
554(* ---------------------------------------------------------------------- *)
555
413ffc02 556let check_rule_name = function
34e49164
C
557 Some nm ->
558 let n = id2name nm in
559 (try let _ = Hashtbl.find Data.all_metadecls n in
560 raise (Semantic_cocci.Semantic ("repeated rule name"))
413ffc02
C
561 with Not_found -> Some n)
562 | None -> None
563
564let make_iso_rule_name_result n =
565 (try let _ = Hashtbl.find Data.all_metadecls n in
566 raise (Semantic_cocci.Semantic ("repeated rule name"))
567 with Not_found -> ());
568 Ast.CocciRulename
569 (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*))
570
571let make_cocci_rule_name_result nm d i a e ee =
572 Ast.CocciRulename (check_rule_name nm,d,i,a,e,ee)
34e49164 573
faf9a90c 574let make_generated_rule_name_result nm d i a e ee =
413ffc02 575 Ast.GeneratedRulename (check_rule_name nm,d,i,a,e,ee)
faf9a90c 576
413ffc02 577let make_script_rule_name_result lang nm deps =
34e49164 578 let l = id2name lang in
413ffc02 579 Ast.ScriptRulename (check_rule_name nm,l,deps)
b1b2de81 580
c3e37e97 581let make_initial_script_rule_name_result lang deps =
b1b2de81 582 let l = id2name lang in
174d1640 583 Ast.InitialScriptRulename(None,l,deps)
b1b2de81 584
c3e37e97 585let make_final_script_rule_name_result lang deps =
b1b2de81 586 let l = id2name lang in
174d1640 587 Ast.FinalScriptRulename(None,l,deps)
978fd7e5
C
588
589(* Allows type alone only when it is void and only when there is only one
590 parameter. This avoids ambiguity problems in the parser. *)
591let verify_parameter_declarations = function
592 [] -> ()
593 | [x] ->
594 (match Ast0.unwrap x with
595 Ast0.Param(t, None) ->
596 (match Ast0.unwrap t with
597 Ast0.BaseType(Ast.VoidType,_) -> ()
598 | _ ->
599 failwith
600 (Printf.sprintf
601 "%d: only void can be a parameter without an identifier"
602 (Ast0.get_line t)))
603 | _ -> ())
604 | l ->
605 List.iter
606 (function x ->
607 match Ast0.unwrap x with
608 Ast0.Param(t, None) ->
609 failwith
610 (Printf.sprintf
611 "%d: only void alone can be a parameter without an identifier"
612 (Ast0.get_line t))
613 | _ -> ())
614 l
c491d8ee
C
615
616(* ---------------------------------------------------------------------- *)
617(* decide whether an init list is ordered or unordered *)
618
619let struct_initializer initlist =
620 let rec loop i =
621 match Ast0.unwrap i with
622 Ast0.InitGccExt _ -> true
623 | Ast0.InitGccName _ -> true
624 | Ast0.OptIni i | Ast0.UniqueIni i -> loop i
8f657093 625 | Ast0.MetaInit _ | Ast0.MetaInitList _ -> false (* ambiguous... *)
c491d8ee
C
626 | _ -> false in
627 let l = Ast0.undots initlist in
628 (l = []) or (List.exists loop l)
629
630let drop_dot_commas initlist =
631 match Ast0.unwrap initlist with
632 Ast0.DOTS(l) ->
633 let rec loop after_comma = function
634 [] -> []
635 | x::xs ->
636 (match Ast0.unwrap x with
637 Ast0.Idots(dots,whencode) -> x :: (loop true xs)
638 | Ast0.IComma(comma) when after_comma -> (*drop*) loop false xs
639 | _ -> x :: (loop false xs)) in
640 Ast0.rewrap initlist (Ast0.DOTS(loop false l))
641 | _ -> failwith "not supported"