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