Release coccinelle-0.2.4rc2
[bpt/coccinelle.git] / parsing_cocci / parse_aux.ml
CommitLineData
34e49164
C
1(* exports everything, used only by parser_cocci_menhir.mly *)
2module Ast0 = Ast0_cocci
3module Ast = Ast_cocci
4
5(* types for metavariable tokens *)
6type info = Ast.meta_name * Ast0.pure * Data.clt
7type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt
8type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt
9type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt
88e71198 10type list_info = Ast.meta_name * Ast.list_len * Ast0.pure * Data.clt
951c7801 11type typed_expinfo =
34e49164
C
12 Ast.meta_name * Data.econstraints * Ast0.pure *
13 Type_cocci.typeC list option * Data.clt
14type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt
15
34e49164
C
16let get_option fn = function
17 None -> None
18 | Some x -> Some (fn x)
19
20let make_info line logical_line offset col strbef straft =
0708f913
C
21 let new_pos_info =
22 {Ast0.line_start = line; Ast0.line_end = line;
23 Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
708f4980 24 Ast0.column = col; Ast0.offset = offset; } in
0708f913 25 { Ast0.pos_info = new_pos_info;
34e49164
C
26 Ast0.attachable_start = true; Ast0.attachable_end = true;
27 Ast0.mcode_start = []; Ast0.mcode_end = [];
34e49164
C
28 Ast0.strings_before = strbef; Ast0.strings_after = straft; }
29
30let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
31 make_info line logical_line offset col strbef straft
32
33let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) =
34 (arity,line,lline,offset,col,[],straft,pos)
35
36let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
37 (arity,line,lline,offset,col,strbef,[],pos)
38
7f004419
C
39let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) =
40 (arity,line,lline,offset,col,strbef,straft,Ast0.NoMetaPos)
41
34e49164
C
42let clt2mcode str = function
43 (Data.MINUS,line,lline,offset,col,strbef,straft,pos) ->
44 (str,Ast0.NONE,make_info line lline offset col strbef straft,
708f4980 45 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164
C
46 | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) ->
47 (str,Ast0.OPT,make_info line lline offset col strbef straft,
708f4980 48 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164
C
49 | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) ->
50 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
708f4980 51 Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1)
34e49164 52 | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) ->
951c7801
C
53 (str,Ast0.NONE,make_info line lline offset col strbef straft,
54 Ast0.PLUS(Ast.ONE),ref pos,-1)
55 | (Data.PLUSPLUS,line,lline,offset,col,strbef,straft,pos) ->
56 (str,Ast0.NONE,make_info line lline offset col strbef straft,
57 Ast0.PLUS(Ast.MANY),ref pos,-1)
34e49164
C
58 | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) ->
59 (str,Ast0.NONE,make_info line lline offset col strbef straft,
60 Ast0.CONTEXT(ref(Ast.NOTHING,
61 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 62 ref pos,-1)
34e49164
C
63 | (Data.OPT,line,lline,offset,col,strbef,straft,pos) ->
64 (str,Ast0.OPT,make_info line lline offset col strbef straft,
65 Ast0.CONTEXT(ref(Ast.NOTHING,
66 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 67 ref pos,-1)
34e49164
C
68 | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) ->
69 (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
70 Ast0.CONTEXT(ref(Ast.NOTHING,
71 Ast0.default_token_info,Ast0.default_token_info)),
708f4980 72 ref pos,-1)
34e49164
C
73
74let id2name (name, clt) = name
75let id2clt (name, clt) = clt
76let id2mcode (name, clt) = clt2mcode name clt
77
78let mkdots str (dot,whencode) =
79 match str with
80 "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode))
81 | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode))
82 | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode))
83 | _ -> failwith "cannot happen"
84
85let mkedots str (dot,whencode) =
86 match str with
87 "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode))
88 | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode))
89 | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode))
90 | _ -> failwith "cannot happen"
91
92let mkdpdots str dot =
93 match str with
94 "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot))
95 | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot))
96 | _ -> failwith "cannot happen"
97
98let mkidots str (dot,whencode) =
99 match str with
100 "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode))
101 | _ -> failwith "cannot happen"
102
103let mkddots str (dot,whencode) =
104 match (str,whencode) with
105 ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None))
106 | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w))
107 | _ -> failwith "cannot happen"
108
109let mkpdots str dot =
110 match str with
111 "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot))
112 | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot))
113 | _ -> failwith "cannot happen"
114
115let arith_op ast_op left op right =
116 Ast0.wrap
117 (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right))
118
119let logic_op ast_op left op right =
120 Ast0.wrap
121 (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right))
122
123let make_cv cv ty =
124 match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty))
125
126let top_dots l =
127 let circle x =
128 match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
129 let star x =
130 match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
131 if List.exists circle l
132 then Ast0.wrap(Ast0.CIRCLES(l))
133 else
134 if List.exists star l
135 then Ast0.wrap(Ast0.STARS(l))
136 else Ast0.wrap(Ast0.DOTS(l))
137
138(* here the offset is that of the first in the sequence of *s, not that of
139each * individually *)
140let pointerify ty m =
141 List.fold_left
142 (function inner ->
143 function cur ->
144 Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur)))
145 ty m
146
147let ty_pointerify ty m =
148 List.fold_left
149 (function inner -> function cur -> Type_cocci.Pointer(inner))
150 ty m
151
152(* Left is <=>, Right is =>. Collect <=>s. *)
153(* The parser should have done this, with precedences. But whatever... *)
c3e37e97 154let iso_adjust first_fn fn first rest =
34e49164
C
155 let rec loop = function
156 [] -> [[]]
157 | (Common.Left x)::rest ->
158 (match loop rest with
159 front::after -> (fn x::front)::after
160 | _ -> failwith "not possible")
161 | (Common.Right x)::rest ->
162 (match loop rest with
163 front::after -> []::(fn x::front)::after
164 | _ -> failwith "not possible") in
165 match loop rest with
c3e37e97 166 front::after -> (first_fn first::front)::after
34e49164
C
167 | _ -> failwith "not possible"
168
174d1640
C
169let lookup rule name =
170 try
171 let info = Hashtbl.find Data.all_metadecls rule in
172 List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info
173 with
174 Not_found ->
175 raise
176 (Semantic_cocci.Semantic("bad rule "^rule^" or bad variable "^name))
177
178let check_meta_tyopt type_irrelevant = function
34e49164
C
179 Ast.MetaIdDecl(Ast.NONE,(rule,name)) ->
180 (match lookup rule name with
181 Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> ()
182 | _ ->
183 raise
184 (Semantic_cocci.Semantic
185 ("incompatible inheritance declaration "^name)))
b1b2de81 186 | Ast.MetaFreshIdDecl((rule,name),seed) ->
34e49164
C
187 raise
188 (Semantic_cocci.Semantic
189 "can't inherit the freshness of an identifier")
190 | Ast.MetaListlenDecl((rule,name)) ->
191 (match lookup rule name with
192 Ast.MetaListlenDecl(_) -> ()
193 | _ ->
194 raise
195 (Semantic_cocci.Semantic
196 ("incompatible inheritance declaration "^name)))
197 | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) ->
198 (match lookup rule name with
199 Ast.MetaTypeDecl(_,_) -> ()
200 | _ ->
201 raise
202 (Semantic_cocci.Semantic
203 ("incompatible inheritance declaration "^name)))
113803cf
C
204 | Ast.MetaInitDecl(Ast.NONE,(rule,name)) ->
205 (match lookup rule name with
206 Ast.MetaInitDecl(_,_) -> ()
207 | _ ->
208 raise
209 (Semantic_cocci.Semantic
210 ("incompatible inheritance declaration "^name)))
34e49164
C
211 | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
212 (match lookup rule name with
213 Ast.MetaParamDecl(_,_) -> ()
214 | _ ->
215 raise
216 (Semantic_cocci.Semantic
217 ("incompatible inheritance declaration "^name)))
218 | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) ->
219 (match lookup rule name with
220 Ast.MetaParamListDecl(_,_,_) -> ()
221 | _ ->
222 raise
223 (Semantic_cocci.Semantic
224 ("incompatible inheritance declaration "^name)))
225 | Ast.MetaErrDecl(Ast.NONE,(rule,name)) ->
226 (match lookup rule name with
227 Ast.MetaErrDecl(_,_) -> ()
228 | _ ->
229 raise
230 (Semantic_cocci.Semantic
231 ("incompatible inheritance declaration "^name)))
232 | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) ->
233 (match lookup rule name with
5636bb2c 234 Ast.MetaExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
235 | _ ->
236 raise
237 (Semantic_cocci.Semantic
238 ("incompatible inheritance declaration "^name)))
239 | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) ->
240 (match lookup rule name with
5636bb2c 241 Ast.MetaIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
242 | _ ->
243 raise
244 (Semantic_cocci.Semantic
245 ("incompatible inheritance declaration "^name)))
246 | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) ->
247 (match lookup rule name with
5636bb2c 248 Ast.MetaLocalIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
249 | _ ->
250 raise
251 (Semantic_cocci.Semantic
252 ("incompatible inheritance declaration "^name)))
253 | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) ->
254 (match lookup rule name with
255 Ast.MetaExpListDecl(_,_,_) -> ()
faf9a90c 256 | Ast.MetaParamListDecl(_,_,_) when not (!Flag.make_hrule = None) -> ()
34e49164
C
257 | _ ->
258 raise
259 (Semantic_cocci.Semantic
260 ("incompatible inheritance declaration "^name)))
261 | Ast.MetaStmDecl(Ast.NONE,(rule,name)) ->
262 (match lookup rule name with
263 Ast.MetaStmDecl(_,_) -> ()
264 | _ ->
265 raise
266 (Semantic_cocci.Semantic
267 ("incompatible inheritance declaration "^name)))
268 | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) ->
269 (match lookup rule name with
270 Ast.MetaStmListDecl(_,_) -> ()
271 | _ ->
272 raise
273 (Semantic_cocci.Semantic
274 ("incompatible inheritance declaration "^name)))
275 | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) ->
276 (match lookup rule name with
277 Ast.MetaFuncDecl(_,_) -> ()
278 | _ ->
279 raise
280 (Semantic_cocci.Semantic
281 ("incompatible inheritance declaration "^name)))
282 | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) ->
283 (match lookup rule name with
284 Ast.MetaLocalFuncDecl(_,_) -> ()
285 | _ ->
286 raise
287 (Semantic_cocci.Semantic
288 ("incompatible inheritance declaration "^name)))
289 | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) ->
290 (match lookup rule name with
5636bb2c 291 Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> ()
34e49164
C
292 | _ ->
293 raise
294 (Semantic_cocci.Semantic
295 ("incompatible inheritance declaration "^name)))
296 | Ast.MetaPosDecl(Ast.NONE,(rule,name)) ->
297 (match lookup rule name with
298 Ast.MetaPosDecl(_,_) ->
299 if not (List.mem rule !Data.inheritable_positions)
300 then
301 raise
302 (Semantic_cocci.Semantic
303 ("position cannot be inherited over modifications: "^name))
304 | _ ->
305 raise
306 (Semantic_cocci.Semantic
307 ("incompatible inheritance declaration "^name)))
308 | _ ->
309 raise
310 (Semantic_cocci.Semantic ("arity not allowed on imported declaration"))
311
5636bb2c
C
312let check_meta m = check_meta_tyopt false m
313
314let check_inherited_constraint meta_name fn =
315 match meta_name with
316 (None,_) -> failwith "constraint must be an inherited variable"
317 | (Some rule,name) ->
318 let i = (rule,name) in
319 check_meta_tyopt true (fn i);
320 i
321
34e49164
C
322let create_metadec ar ispure kindfn ids current_rule =
323 List.concat
324 (List.map
325 (function (rule,nm) ->
326 let (rule,checker) =
327 match rule with
328 None -> ((current_rule,nm),function x -> [Common.Left x])
329 | Some rule ->
330 ((rule,nm),
331 function x -> check_meta x; [Common.Right x]) in
332 kindfn ar rule ispure checker)
333 ids)
334
ae4735db
C
335
336let create_metadec_virt ar ispure kindfn ids current_rule =
337 List.concat
338 (List.map
339 (function nm ->
340 let checker = function x -> [Common.Right x] in
341 kindfn ar nm ispure checker !Flag.defined_virtual_env)
342 ids)
343
b1b2de81
C
344let create_fresh_metadec kindfn ids current_rule =
345 List.concat
346 (List.map
347 (function ((rule,nm),seed) ->
348 let (rule,checker) =
349 match rule with
350 None -> ((current_rule,nm),function x -> [Common.Left x])
351 | Some rule ->
352 ((rule,nm),
353 function x -> check_meta x; [Common.Right x]) in
354 kindfn rule checker seed)
355 ids)
356
951c7801 357let create_metadec_with_constraints ar ispure kindfn ids current_rule =
34e49164
C
358 List.concat
359 (List.map
360 (function ((rule,nm),constraints) ->
361 let (rule,checker) =
362 match rule with
951c7801
C
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 ar rule ispure checker constraints)
34e49164
C
368 ids)
369
370let create_metadec_ty ar ispure kindfn ids current_rule =
371 List.concat
372 (List.map
373 (function ((rule,nm),constraints) ->
374 let (rule,checker) =
375 match rule with
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)
381 ids)
382
383let create_len_metadec ar ispure kindfn lenid ids current_rule =
88e71198
C
384 let (lendec,lenname) =
385 match lenid with
386 Common.Left lenid ->
387 let lendec =
388 create_metadec Ast.NONE Ast0.Impure
389 (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name)))
390 [lenid] current_rule in
391 let lenname =
392 match lendec with
393 [Common.Left (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
394 | [Common.Right (Ast.MetaListlenDecl(x))] -> Ast.MetaLen x
395 | _ -> failwith "unexpected length declaration" in
396 (lendec,lenname)
397 | Common.Right n -> ([],Ast.CstLen n) in
34e49164
C
398 lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule)
399
400(* ---------------------------------------------------------------------- *)
401
402let str2inc s =
403 let elements = Str.split (Str.regexp "/") s in
404 List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements
405
406(* ---------------------------------------------------------------------- *)
413ffc02
C
407(* declarations and statements *)
408
409let meta_decl name =
410 let (nm,pure,clt) = name in
411 Ast0.wrap(Ast0.MetaDecl(clt2mcode nm clt,pure))
412
413let meta_field name =
414 let (nm,pure,clt) = name in
415 Ast0.wrap(Ast0.MetaField(clt2mcode nm clt,pure))
34e49164
C
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
413ffc02 489let check_rule_name = function
34e49164
C
490 Some nm ->
491 let n = id2name nm in
492 (try let _ = Hashtbl.find Data.all_metadecls n in
493 raise (Semantic_cocci.Semantic ("repeated rule name"))
413ffc02
C
494 with Not_found -> Some n)
495 | None -> None
496
497let make_iso_rule_name_result n =
498 (try let _ = Hashtbl.find Data.all_metadecls n in
499 raise (Semantic_cocci.Semantic ("repeated rule name"))
500 with Not_found -> ());
501 Ast.CocciRulename
502 (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*))
503
504let make_cocci_rule_name_result nm d i a e ee =
505 Ast.CocciRulename (check_rule_name nm,d,i,a,e,ee)
34e49164 506
faf9a90c 507let make_generated_rule_name_result nm d i a e ee =
413ffc02 508 Ast.GeneratedRulename (check_rule_name nm,d,i,a,e,ee)
faf9a90c 509
413ffc02 510let make_script_rule_name_result lang nm deps =
34e49164 511 let l = id2name lang in
413ffc02 512 Ast.ScriptRulename (check_rule_name nm,l,deps)
b1b2de81 513
c3e37e97 514let make_initial_script_rule_name_result lang deps =
b1b2de81 515 let l = id2name lang in
174d1640 516 Ast.InitialScriptRulename(None,l,deps)
b1b2de81 517
c3e37e97 518let make_final_script_rule_name_result lang deps =
b1b2de81 519 let l = id2name lang in
174d1640 520 Ast.FinalScriptRulename(None,l,deps)
978fd7e5
C
521
522(* Allows type alone only when it is void and only when there is only one
523 parameter. This avoids ambiguity problems in the parser. *)
524let verify_parameter_declarations = function
525 [] -> ()
526 | [x] ->
527 (match Ast0.unwrap x with
528 Ast0.Param(t, None) ->
529 (match Ast0.unwrap t with
530 Ast0.BaseType(Ast.VoidType,_) -> ()
531 | _ ->
532 failwith
533 (Printf.sprintf
534 "%d: only void can be a parameter without an identifier"
535 (Ast0.get_line t)))
536 | _ -> ())
537 | l ->
538 List.iter
539 (function x ->
540 match Ast0.unwrap x with
541 Ast0.Param(t, None) ->
542 failwith
543 (Printf.sprintf
544 "%d: only void alone can be a parameter without an identifier"
545 (Ast0.get_line t))
546 | _ -> ())
547 l