2 * Copyright 2012, INRIA
3 * Julia Lawall, Gilles Muller
4 * Copyright 2010-2011, INRIA, University of Copenhagen
5 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
6 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
7 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
8 * This file is part of Coccinelle.
10 * Coccinelle is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, according to version 2 of the License.
14 * Coccinelle is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
22 * The authors reserve the right to distribute this or future versions of
23 * Coccinelle under other licenses.
28 (* exports everything, used only by parser_cocci_menhir.mly *)
29 module Ast0
= Ast0_cocci
30 module Ast
= Ast_cocci
32 (* types for metavariable tokens *)
33 type info
= Ast.meta_name
* Ast0.pure
* Data.clt
35 Ast.meta_name
* Data.iconstraints
* Ast.seed
* Ast0.pure
* Data.clt
36 type idinfo
= Ast.meta_name
* Data.iconstraints
* Ast0.pure
* Data.clt
37 type expinfo
= Ast.meta_name
* Data.econstraints
* Ast0.pure
* Data.clt
38 type tyinfo
= Ast.meta_name
* Ast0.typeC list
* Ast0.pure
* Data.clt
39 type list_info
= Ast.meta_name
* Ast.list_len
* Ast0.pure
* Data.clt
41 Ast.meta_name
* Data.econstraints
* Ast0.pure
*
42 Type_cocci.typeC list
option * Data.clt
43 type pos_info
= Ast.meta_name
* Data.pconstraints
* Ast.meta_collect
* Data.clt
45 let get_option fn
= function
47 | Some x
-> Some
(fn x
)
49 let make_info line logical_line offset col strbef straft isSymbol
=
51 {Ast0.line_start
= line
; Ast0.line_end
= line
;
52 Ast0.logical_start
= logical_line
; Ast0.logical_end
= logical_line
;
53 Ast0.column
= col
; Ast0.offset
= offset
; } in
54 { Ast0.pos_info
= new_pos_info;
55 Ast0.attachable_start
= true; Ast0.attachable_end
= true;
56 Ast0.mcode_start
= []; Ast0.mcode_end
= [];
57 Ast0.strings_before
= strbef
; Ast0.strings_after
= straft
;
58 Ast0.isSymbolIdent
= isSymbol
; }
60 let clt2info (_
,line
,logical_line
,offset
,col
,strbef
,straft
,pos
) =
61 make_info line logical_line offset col strbef straft
false
63 let drop_bef (arity
,line
,lline
,offset
,col
,strbef
,straft
,pos
) =
64 (arity
,line
,lline
,offset
,col
,[],straft
,pos
)
66 let drop_aft (arity
,line
,lline
,offset
,col
,strbef
,straft
,pos
) =
67 (arity
,line
,lline
,offset
,col
,strbef
,[],pos
)
69 (* used for #define, to put aft on ident/( *)
70 let get_aft (arity
,line
,lline
,offset
,col
,strbef
,straft
,pos
) = straft
72 let set_aft aft
(arity
,line
,lline
,offset
,col
,strbef
,_
,pos
) =
73 (arity
,line
,lline
,offset
,col
,strbef
,aft
,pos
)
75 let drop_pos (arity
,line
,lline
,offset
,col
,strbef
,straft
,pos
) =
76 (arity
,line
,lline
,offset
,col
,strbef
,straft
,[])
78 let clt2mcode_ext str isSymbol
= function
79 (Data.MINUS
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
80 (str
,Ast0.NONE
,make_info line lline offset col strbef straft isSymbol
,
81 Ast0.MINUS
(ref(Ast.NOREPLACEMENT
,Ast0.default_token_info
)),ref pos
,-1)
82 | (Data.OPTMINUS
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
83 (str
,Ast0.OPT
,make_info line lline offset col strbef straft isSymbol
,
84 Ast0.MINUS
(ref(Ast.NOREPLACEMENT
,Ast0.default_token_info
)),ref pos
,-1)
85 | (Data.UNIQUEMINUS
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
86 (str
,Ast0.UNIQUE
,make_info line lline offset col strbef straft isSymbol
,
87 Ast0.MINUS
(ref(Ast.NOREPLACEMENT
,Ast0.default_token_info
)),ref pos
,-1)
88 | (Data.PLUS
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
89 (str
,Ast0.NONE
,make_info line lline offset col strbef straft isSymbol
,
90 Ast0.PLUS
(Ast.ONE
),ref pos
,-1)
91 | (Data.PLUSPLUS
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
92 (str
,Ast0.NONE
,make_info line lline offset col strbef straft isSymbol
,
93 Ast0.PLUS
(Ast.MANY
),ref pos
,-1)
94 | (Data.CONTEXT
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
95 (str
,Ast0.NONE
,make_info line lline offset col strbef straft isSymbol
,
96 Ast0.CONTEXT
(ref(Ast.NOTHING
,
97 Ast0.default_token_info
,Ast0.default_token_info
)),
99 | (Data.OPT
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
100 (str
,Ast0.OPT
,make_info line lline offset col strbef straft isSymbol
,
101 Ast0.CONTEXT
(ref(Ast.NOTHING
,
102 Ast0.default_token_info
,Ast0.default_token_info
)),
104 | (Data.UNIQUE
,line
,lline
,offset
,col
,strbef
,straft
,pos
) ->
105 (str
,Ast0.UNIQUE
,make_info line lline offset col strbef straft isSymbol
,
106 Ast0.CONTEXT
(ref(Ast.NOTHING
,
107 Ast0.default_token_info
,Ast0.default_token_info
)),
110 let clt2mcode name clt
= clt2mcode_ext name
false clt
111 let id2name (name
, clt
) = name
112 let id2clt (name
, clt
) = clt
113 let id2mcode (name
, clt
) = clt2mcode name clt
114 let sym2mcode (name
, clt
) = clt2mcode_ext name
true clt
116 let mkdots str
(dot
,whencode
) =
118 "..." -> Ast0.wrap
(Ast0.Dots
(clt2mcode str dot
, whencode
))
119 | "ooo" -> Ast0.wrap
(Ast0.Circles
(clt2mcode str dot
, whencode
))
120 | "***" -> Ast0.wrap
(Ast0.Stars
(clt2mcode str dot
, whencode
))
121 | _
-> failwith
"cannot happen"
123 let mkedots str
(dot
,whencode
) =
125 "..." -> Ast0.wrap
(Ast0.Edots
(clt2mcode str dot
, whencode
))
126 | "ooo" -> Ast0.wrap
(Ast0.Ecircles
(clt2mcode str dot
, whencode
))
127 | "***" -> Ast0.wrap
(Ast0.Estars
(clt2mcode str dot
, whencode
))
128 | _
-> failwith
"cannot happen"
130 let mkdpdots str dot
=
132 "..." -> Ast0.wrap
(Ast0.DPdots
(clt2mcode str dot
))
133 | "ooo" -> Ast0.wrap
(Ast0.DPcircles
(clt2mcode str dot
))
134 | _
-> failwith
"cannot happen"
136 let mkidots str
(dot
,whencode
) =
138 "..." -> Ast0.wrap
(Ast0.Idots
(clt2mcode str dot
, whencode
))
139 | _
-> failwith
"cannot happen"
141 let mkddots str
(dot
,whencode
) =
142 match (str
,whencode
) with
143 ("...",None
) -> Ast0.wrap
(Ast0.Ddots
(clt2mcode str dot
, None
))
144 | ("...",Some
[w
]) -> Ast0.wrap
(Ast0.Ddots
(clt2mcode str dot
, Some w
))
145 | _
-> failwith
"cannot happen"
147 let mkddots_one str
(dot
,whencode
) =
149 "..." -> Ast0.wrap
(Ast0.Ddots
(clt2mcode str dot
, whencode
))
150 | _
-> failwith
"cannot happen"
152 let mkpdots str dot
=
154 "..." -> Ast0.wrap
(Ast0.Pdots
(clt2mcode str dot
))
155 | "ooo" -> Ast0.wrap
(Ast0.Pcircles
(clt2mcode str dot
))
156 | _
-> failwith
"cannot happen"
158 let arith_op ast_op left op right
=
160 (Ast0.Binary
(left
, clt2mcode (Ast.Arith ast_op
) op
, right
))
162 let logic_op ast_op left op right
=
164 (Ast0.Binary
(left
, clt2mcode (Ast.Logical ast_op
) op
, right
))
167 match cv
with None
-> ty
| Some x
-> Ast0.wrap
(Ast0.ConstVol
(x
,ty
))
171 match Ast0.unwrap x
with Ast0.Circles
(_
) -> true | _
-> false in
173 match Ast0.unwrap x
with Ast0.Stars
(_
) -> true | _
-> false in
174 if List.exists
circle l
175 then Ast0.wrap
(Ast0.CIRCLES
(l
))
177 if List.exists
star l
178 then Ast0.wrap
(Ast0.STARS
(l
))
179 else Ast0.wrap
(Ast0.DOTS
(l
))
181 (* here the offset is that of the first in the sequence of *s, not that of
182 each * individually *)
183 let pointerify ty m
=
187 Ast0.wrap
(Ast0.Pointer
(inner
,clt2mcode "*" cur
)))
190 let ty_pointerify ty m
=
192 (function inner
-> function cur
-> Type_cocci.Pointer
(inner
))
199 Ast0.wrap
(Ast0.Array
(rest
,clt2mcode "[" l
,i
,clt2mcode "]" r
)))
202 (* Left is <=>, Right is =>. Collect <=>s. *)
203 (* The parser should have done this, with precedences. But whatever... *)
204 let iso_adjust first_fn fn first rest
=
205 let rec loop = function
207 | (Common.Left x
)::rest
->
208 (match loop rest
with
209 front
::after
-> (fn x
::front
)::after
210 | _
-> failwith
"not possible")
211 | (Common.Right x
)::rest
->
212 (match loop rest
with
213 front
::after
-> []::(fn x
::front
)::after
214 | _
-> failwith
"not possible") in
216 front
::after
-> (first_fn first
::front
)::after
217 | _
-> failwith
"not possible"
219 let lookup rule name
=
221 let info = Hashtbl.find
Data.all_metadecls rule
in
222 List.find
(function mv
-> Ast.get_meta_name mv
= (rule
,name
)) info
226 (Semantic_cocci.Semantic
("bad rule "^rule^
" or bad variable "^name
))
228 let check_meta_tyopt type_irrelevant
= function
229 Ast.MetaMetaDecl
(Ast.NONE
,(rule
,name
)) ->
230 (match lookup rule name
with
231 Ast.MetaMetaDecl
(_
,_
) -> ()
234 (Semantic_cocci.Semantic
235 ("incompatible inheritance declaration "^name
)))
236 | Ast.MetaIdDecl
(Ast.NONE
,(rule
,name
)) ->
237 (match lookup rule name
with
238 Ast.MetaIdDecl
(_
,_
) | Ast.MetaFreshIdDecl
(_
,_
) -> ()
241 (Semantic_cocci.Semantic
242 ("incompatible inheritance declaration "^name
)))
243 | Ast.MetaFreshIdDecl
((rule
,name
),seed
) ->
245 (Semantic_cocci.Semantic
246 "can't inherit the freshness of an identifier")
247 | Ast.MetaTypeDecl
(Ast.NONE
,(rule
,name
)) ->
248 (match lookup rule name
with
249 Ast.MetaTypeDecl
(_
,_
) -> ()
252 (Semantic_cocci.Semantic
253 ("incompatible inheritance declaration "^name
)))
254 | Ast.MetaInitDecl
(Ast.NONE
,(rule
,name
)) ->
255 (match lookup rule name
with
256 Ast.MetaInitDecl
(_
,_
) -> ()
259 (Semantic_cocci.Semantic
260 ("incompatible inheritance declaration "^name
)))
261 | Ast.MetaInitListDecl
(Ast.NONE
,(rule
,name
),len_name
) ->
262 (match lookup rule name
with
263 Ast.MetaInitListDecl
(_
,_
,_
) -> ()
266 (Semantic_cocci.Semantic
267 ("incompatible inheritance declaration "^name
)))
268 | Ast.MetaListlenDecl
((rule
,name
)) ->
269 (match lookup rule name
with
270 Ast.MetaListlenDecl
(_
) -> ()
273 (Semantic_cocci.Semantic
274 ("incompatible inheritance declaration "^name
)))
275 | Ast.MetaParamDecl
(Ast.NONE
,(rule
,name
)) ->
276 (match lookup rule name
with
277 Ast.MetaParamDecl
(_
,_
) -> ()
280 (Semantic_cocci.Semantic
281 ("incompatible inheritance declaration "^name
)))
282 | Ast.MetaParamListDecl
(Ast.NONE
,(rule
,name
),len_name
) ->
283 (match lookup rule name
with
284 Ast.MetaParamListDecl
(_
,_
,_
) -> ()
287 (Semantic_cocci.Semantic
288 ("incompatible inheritance declaration "^name
)))
289 | Ast.MetaConstDecl
(Ast.NONE
,(rule
,name
),ty
) ->
290 (match lookup rule name
with
291 Ast.MetaConstDecl
(_
,_
,ty1
) when type_irrelevant
or ty
= ty1
-> ()
294 (Semantic_cocci.Semantic
295 ("incompatible inheritance declaration "^name
)))
296 | Ast.MetaErrDecl
(Ast.NONE
,(rule
,name
)) ->
297 (match lookup rule name
with
298 Ast.MetaErrDecl
(_
,_
) -> ()
301 (Semantic_cocci.Semantic
302 ("incompatible inheritance declaration "^name
)))
303 | Ast.MetaExpDecl
(Ast.NONE
,(rule
,name
),ty
) ->
304 (match lookup rule name
with
305 Ast.MetaExpDecl
(_
,_
,ty1
) when type_irrelevant
or ty
= ty1
-> ()
308 (Semantic_cocci.Semantic
309 ("incompatible inheritance declaration "^name
)))
310 | Ast.MetaIdExpDecl
(Ast.NONE
,(rule
,name
),ty
) ->
311 (match lookup rule name
with
312 Ast.MetaIdExpDecl
(_
,_
,ty1
) when type_irrelevant
or ty
= ty1
-> ()
315 (Semantic_cocci.Semantic
316 ("incompatible inheritance declaration "^name
)))
317 | Ast.MetaLocalIdExpDecl
(Ast.NONE
,(rule
,name
),ty
) ->
318 (match lookup rule name
with
319 Ast.MetaLocalIdExpDecl
(_
,_
,ty1
) when type_irrelevant
or ty
= ty1
-> ()
322 (Semantic_cocci.Semantic
323 ("incompatible inheritance declaration "^name
)))
324 | Ast.MetaExpListDecl
(Ast.NONE
,(rule
,name
),len_name
) ->
325 (match lookup rule name
with
326 Ast.MetaExpListDecl
(_
,_
,_
) -> ()
327 | Ast.MetaParamListDecl
(_
,_
,_
) when not
(!Flag.make_hrule
= None
) -> ()
330 (Semantic_cocci.Semantic
331 ("incompatible inheritance declaration "^name
)))
332 | Ast.MetaDeclDecl
(Ast.NONE
,(rule
,name
)) ->
333 (match lookup rule name
with
334 Ast.MetaDeclDecl
(_
,_
) -> ()
337 (Semantic_cocci.Semantic
338 ("incompatible inheritance declaration "^name
)))
339 | Ast.MetaFieldDecl
(Ast.NONE
,(rule
,name
)) ->
340 (match lookup rule name
with
341 Ast.MetaFieldDecl
(_
,_
) -> ()
344 (Semantic_cocci.Semantic
345 ("incompatible inheritance declaration "^name
)))
346 | Ast.MetaFieldListDecl
(Ast.NONE
,(rule
,name
),len_name
) ->
347 (match lookup rule name
with
348 Ast.MetaFieldListDecl
(_
,_
,_
) -> ()
351 (Semantic_cocci.Semantic
352 ("incompatible inheritance declaration "^name
)))
353 | Ast.MetaStmDecl
(Ast.NONE
,(rule
,name
)) ->
354 (match lookup rule name
with
355 Ast.MetaStmDecl
(_
,_
) -> ()
358 (Semantic_cocci.Semantic
359 ("incompatible inheritance declaration "^name
)))
360 | Ast.MetaStmListDecl
(Ast.NONE
,(rule
,name
)) ->
361 (match lookup rule name
with
362 Ast.MetaStmListDecl
(_
,_
) -> ()
365 (Semantic_cocci.Semantic
366 ("incompatible inheritance declaration "^name
)))
367 | Ast.MetaFuncDecl
(Ast.NONE
,(rule
,name
)) ->
368 (match lookup rule name
with
369 Ast.MetaFuncDecl
(_
,_
) -> ()
372 (Semantic_cocci.Semantic
373 ("incompatible inheritance declaration "^name
)))
374 | Ast.MetaLocalFuncDecl
(Ast.NONE
,(rule
,name
)) ->
375 (match lookup rule name
with
376 Ast.MetaLocalFuncDecl
(_
,_
) -> ()
379 (Semantic_cocci.Semantic
380 ("incompatible inheritance declaration "^name
)))
381 | Ast.MetaPosDecl
(Ast.NONE
,(rule
,name
)) ->
382 (match lookup rule name
with
383 Ast.MetaPosDecl
(_
,_
) ->
384 if not
(List.mem rule
!Data.inheritable_positions
) &&
385 not
!Data.ignore_patch_or_match
388 (Semantic_cocci.Semantic
389 ("position cannot be inherited over modifications: "^name
))
392 (Semantic_cocci.Semantic
393 ("incompatible inheritance declaration "^name
)))
396 (Semantic_cocci.Semantic
("arity not allowed on imported declaration"))
398 let check_meta m
= check_meta_tyopt false m
400 let check_inherited_constraint meta_name fn
=
402 (None
,_
) -> failwith
"constraint must be an inherited variable"
403 | (Some rule
,name
) ->
404 let i = (rule
,name
) in
405 check_meta_tyopt true (fn
i);
408 let create_metadec ar ispure kindfn ids current_rule
=
411 (function (rule
,nm
) ->
414 None
-> ((current_rule
,nm
),function x
-> [Common.Left x
])
417 function x
-> check_meta x
; [Common.Right x
]) in
418 kindfn ar rule ispure checker
)
422 let create_metadec_virt ar ispure kindfn ids current_rule
=
426 let checker = function x
-> [Common.Right x
] in
427 kindfn ar nm ispure
checker !Flag.defined_virtual_env
)
430 let create_fresh_metadec kindfn ids current_rule
=
433 (function ((rule
,nm
),seed
) ->
436 None
-> ((current_rule
,nm
),function x
-> [Common.Left x
])
439 function x
-> check_meta x
; [Common.Right x
]) in
440 kindfn rule
checker seed
)
443 let create_metadec_with_constraints ar ispure kindfn ids current_rule
=
446 (function ((rule
,nm
),constraints
) ->
449 None
-> ((current_rule
,nm
),function x
-> [Common.Left x
])
452 function x
-> check_meta x
; [Common.Right x
]) in
453 kindfn ar rule ispure
checker constraints
)
456 let create_metadec_ty ar ispure kindfn ids current_rule
=
459 (function ((rule
,nm
),constraints
) ->
462 None
-> ((current_rule
,nm
),function x
-> [Common.Left x
])
465 function x
-> check_meta x
; [Common.Right x
]) in
466 kindfn ar rule ispure
checker constraints
)
469 let create_len_metadec ar ispure kindfn lenid ids current_rule
=
470 let (lendec
,lenname
) =
474 create_metadec Ast.NONE
Ast0.Impure
475 (fun _ name _
check_meta -> check_meta(Ast.MetaListlenDecl
(name
)))
476 [lenid
] current_rule
in
479 [Common.Left
(Ast.MetaListlenDecl
(x
))] -> Ast.MetaLen x
480 | [Common.Right
(Ast.MetaListlenDecl
(x
))] -> Ast.MetaLen x
481 | _
-> failwith
"unexpected length declaration" in
483 | Common.Right n
-> ([],Ast.CstLen n
) in
484 lendec@(create_metadec ar ispure
(kindfn
lenname) ids current_rule
)
486 (* ---------------------------------------------------------------------- *)
489 let elements = Str.split
(Str.regexp
"/") s
in
490 List.map
(function "..." -> Ast.IncDots
| s
-> Ast.IncPath s
) elements
492 (* ---------------------------------------------------------------------- *)
493 (* declarations and statements *)
496 let (nm
,pure
,clt
) = name
in
497 Ast0.wrap
(Ast0.MetaDecl
(clt2mcode nm clt
,pure
))
499 let meta_field name
=
500 let (nm
,pure
,clt
) = name
in
501 Ast0.wrap
(Ast0.MetaField
(clt2mcode nm clt
,pure
))
503 let meta_field_list name
=
504 let (nm
,lenname,pure
,clt
) = name
in
507 Ast.AnyLen
-> Ast0.AnyListLen
508 | Ast.MetaLen nm
-> Ast0.MetaListLen
(clt2mcode nm clt
)
509 | Ast.CstLen n
-> Ast0.CstListLen n
in
510 Ast0.wrap
(Ast0.MetaFieldList
(clt2mcode nm clt
,lenname,pure
))
513 let (nm
,pure
,clt
) = name
in
514 Ast0.wrap
(Ast0.MetaStmt
(clt2mcode nm clt
,pure
))
517 Ast0.wrap
(Ast0.ExprStatement
(exp
, clt2mcode ";" pv
))
519 let make_fake_mcode _
= (Ast0.default_info
(),Ast0.context_befaft
(),-1)
521 let ifthen iff lp tst rp thn
=
522 Ast0.wrap
(Ast0.IfThen
(clt2mcode "if" iff
,
523 clt2mcode "(" lp
,tst
,clt2mcode ")" rp
,thn
,make_fake_mcode()))
525 let ifthenelse iff lp tst rp thn e els
=
526 Ast0.wrap
(Ast0.IfThenElse
(clt2mcode "if" iff
,
527 clt2mcode "(" lp
,tst
,clt2mcode ")" rp
,thn
,
528 clt2mcode "else" e
,els
,make_fake_mcode()))
530 let forloop fr lp e1 sc1 e2 sc2 e3 rp s
=
531 Ast0.wrap
(Ast0.For
(clt2mcode "for" fr
,clt2mcode "(" lp
,
532 Ast0.wrap
(Ast0.ForExp
(e1
,clt2mcode ";" sc1
)),e2
,
533 clt2mcode ";" sc2
,e3
,clt2mcode ")" rp
,s
,
536 let forloop2 fr lp decl e2 sc2 e3 rp s
=
537 let bef = (Ast0.default_info
(),Ast0.context_befaft
()) in
538 Ast0.wrap
(Ast0.For
(clt2mcode "for" fr
,clt2mcode "(" lp
,
539 Ast0.wrap
(Ast0.ForDecl
(bef,decl
)),e2
,
540 clt2mcode ";" sc2
,e3
,clt2mcode ")" rp
,s
,
543 let whileloop w lp e rp s
=
544 Ast0.wrap
(Ast0.While
(clt2mcode "while" w
,clt2mcode "(" lp
,
545 e
,clt2mcode ")" rp
,s
,make_fake_mcode()))
547 let doloop d s w lp e rp pv
=
548 Ast0.wrap
(Ast0.Do
(clt2mcode "do" d
,s
,clt2mcode "while" w
,
549 clt2mcode "(" lp
,e
,clt2mcode ")" rp
,
552 let iterator i lp e rp s
=
553 Ast0.wrap
(Ast0.Iterator
(i,clt2mcode "(" lp
,e
,clt2mcode ")" rp
,s
,
556 let switch s lp e rp lb d c rb
=
560 Ast0.wrap
(Ast0.Decl
((Ast0.default_info
(),Ast0.context_befaft
()),d)))
562 Ast0.wrap
(Ast0.Switch
(clt2mcode "switch" s
,clt2mcode "(" lp
,e
,
563 clt2mcode ")" rp
,clt2mcode "{" lb
,
564 Ast0.wrap
(Ast0.DOTS
(d)),
565 Ast0.wrap
(Ast0.DOTS
(c
)),clt2mcode "}" rb
))
568 Ast0.wrap
(Ast0.ReturnExpr
(clt2mcode "return" r
,e
,clt2mcode ";" pv
))
571 Ast0.wrap
(Ast0.Return
(clt2mcode "return" r
,clt2mcode ";" pv
))
574 Ast0.wrap
(Ast0.Break
(clt2mcode "break" b
,clt2mcode ";" pv
))
577 Ast0.wrap
(Ast0.Continue
(clt2mcode "continue" c
,clt2mcode ";" pv
))
580 Ast0.wrap
(Ast0.Label
(i,clt2mcode ":" dd
))
583 Ast0.wrap
(Ast0.Goto
(clt2mcode "goto" g
,i,clt2mcode ";" pv
))
586 Ast0.wrap
(Ast0.Seq
(clt2mcode "{" lb
,s
,clt2mcode "}" rb
))
588 (* ---------------------------------------------------------------------- *)
590 let check_rule_name = function
592 let n = id2name nm
in
593 (try let _ = Hashtbl.find
Data.all_metadecls
n in
594 raise
(Semantic_cocci.Semantic
("repeated rule name"))
595 with Not_found
-> Some
n)
598 let make_iso_rule_name_result n =
599 (try let _ = Hashtbl.find
Data.all_metadecls
n in
600 raise
(Semantic_cocci.Semantic
("repeated rule name"))
601 with Not_found
-> ());
603 (Some
n,Ast.NoDep
,[],[],Ast.Undetermined
,false (*discarded*))
605 let fix_dependencies d =
606 let rec loop inverted
= function
607 Ast0.Dep s
when inverted
-> Ast.AntiDep s
608 | Ast0.Dep s
-> Ast.Dep s
609 | Ast0.AntiDep
d -> loop (not inverted
) d
610 | Ast0.EverDep s
when inverted
-> Ast.NeverDep s
611 | Ast0.EverDep s
-> Ast.EverDep s
612 | Ast0.NeverDep s
when inverted
-> Ast.EverDep s
613 | Ast0.NeverDep s
-> Ast.NeverDep s
614 | Ast0.AndDep
(d1
,d2
) when inverted
->
615 Ast.OrDep
(loop inverted d1
,loop inverted d2
)
616 | Ast0.AndDep
(d1
,d2
) ->
617 Ast.AndDep
(loop inverted d1
,loop inverted d2
)
618 | Ast0.OrDep
(d1
,d2
) when inverted
->
619 Ast.AndDep
(loop inverted d1
,loop inverted d2
)
620 | Ast0.OrDep
(d1
,d2
) ->
621 Ast.OrDep
(loop inverted d1
,loop inverted d2
)
622 | Ast0.NoDep
-> Ast.NoDep
623 | Ast0.FailDep
-> Ast.FailDep
in
626 let make_cocci_rule_name_result nm
d i a e ee
=
627 Ast.CocciRulename
(check_rule_name nm
,fix_dependencies d,i,a
,e
,ee
)
629 let make_generated_rule_name_result nm
d i a e ee
=
630 Ast.GeneratedRulename
(check_rule_name nm
,fix_dependencies d,i,a
,e
,ee
)
632 let make_script_rule_name_result lang nm deps
=
633 let l = id2name lang
in
634 Ast.ScriptRulename
(check_rule_name nm
,l,fix_dependencies deps
)
636 let make_initial_script_rule_name_result lang deps
=
637 let l = id2name lang
in
638 Ast.InitialScriptRulename
(None
,l,fix_dependencies deps
)
640 let make_final_script_rule_name_result lang deps
=
641 let l = id2name lang
in
642 Ast.FinalScriptRulename
(None
,l,fix_dependencies deps
)
644 (* Allows type alone only when it is void and only when there is only one
645 parameter. This avoids ambiguity problems in the parser. *)
646 let verify_parameter_declarations = function
649 (match Ast0.unwrap x
with
650 Ast0.Param
(t
, None
) ->
651 (match Ast0.unwrap t
with
652 Ast0.BaseType
(Ast.VoidType
,_) -> ()
656 "%d: only void can be a parameter without an identifier"
662 match Ast0.unwrap x
with
663 Ast0.Param
(t
, None
) ->
666 "%d: only void alone can be a parameter without an identifier"
671 (* ---------------------------------------------------------------------- *)
672 (* decide whether an init list is ordered or unordered *)
674 let struct_initializer initlist
=
676 match Ast0.unwrap
i with
677 Ast0.InitGccExt
_ -> true
678 | Ast0.InitGccName
_ -> true
679 | Ast0.OptIni
i | Ast0.UniqueIni
i -> loop i
680 | Ast0.MetaInit
_ | Ast0.MetaInitList
_ -> false (* ambiguous... *)
682 let l = Ast0.undots initlist
in
683 (l = []) or (List.exists
loop l)
685 let drop_dot_commas initlist
=
686 match Ast0.unwrap initlist
with
688 let rec loop after_comma
= function
691 (match Ast0.unwrap x
with
692 Ast0.Idots
(dots
,whencode
) -> x
:: (loop true xs
)
693 | Ast0.IComma
(comma
) when after_comma
-> (*drop*) loop false xs
694 | _ -> x
:: (loop false xs
)) in
695 Ast0.rewrap initlist
(Ast0.DOTS
(loop false l))
696 | _ -> failwith
"not supported"