X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/113803cf8147c1b5332cc7d9ac43febcc197e4f0..5636bb2c2537506718da74f85a2b81a5ff3df16f:/parsing_cocci/parse_aux.ml diff --git a/parsing_cocci/parse_aux.ml b/parsing_cocci/parse_aux.ml index 91df7e7..7813f63 100644 --- a/parsing_cocci/parse_aux.ml +++ b/parsing_cocci/parse_aux.ml @@ -1,23 +1,45 @@ (* -* Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen -* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller -* This file is part of Coccinelle. -* -* Coccinelle is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, according to version 2 of the License. -* -* Coccinelle is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with Coccinelle. If not, see . -* -* The authors reserve the right to distribute this or future versions of -* Coccinelle under other licenses. -*) + * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen + * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix + * This file is part of Coccinelle. + * + * Coccinelle is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, according to version 2 of the License. + * + * Coccinelle is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Coccinelle. If not, see . + * + * The authors reserve the right to distribute this or future versions of + * Coccinelle under other licenses. + *) + + +(* + * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen + * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix + * This file is part of Coccinelle. + * + * Coccinelle is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, according to version 2 of the License. + * + * Coccinelle is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Coccinelle. If not, see . + * + * The authors reserve the right to distribute this or future versions of + * Coccinelle under other licenses. + *) (* exports everything, used only by parser_cocci_menhir.mly *) @@ -30,22 +52,23 @@ type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt type list_info = Ast.meta_name * Ast.meta_name option * Ast0.pure * Data.clt -type typed_info = +type typed_expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Type_cocci.typeC list option * Data.clt type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt - let get_option fn = function None -> None | Some x -> Some (fn x) let make_info line logical_line offset col strbef straft = - { Ast0.line_start = line; Ast0.line_end = line; - Ast0.logical_start = logical_line; Ast0.logical_end = logical_line; + let new_pos_info = + {Ast0.line_start = line; Ast0.line_end = line; + Ast0.logical_start = logical_line; Ast0.logical_end = logical_line; + Ast0.column = col; Ast0.offset = offset; } in + { Ast0.pos_info = new_pos_info; Ast0.attachable_start = true; Ast0.attachable_end = true; Ast0.mcode_start = []; Ast0.mcode_end = []; - Ast0.column = col; Ast0.offset = offset; Ast0.strings_before = strbef; Ast0.strings_after = straft; } let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) = @@ -57,34 +80,40 @@ let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) = let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) = (arity,line,lline,offset,col,strbef,[],pos) +let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) = + (arity,line,lline,offset,col,strbef,straft,Ast0.NoMetaPos) + let clt2mcode str = function (Data.MINUS,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.NONE,make_info line lline offset col strbef straft, - Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1) | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.OPT,make_info line lline offset col strbef straft, - Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1) | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.UNIQUE,make_info line lline offset col strbef straft, - Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos,-1) | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) -> - (str,Ast0.NONE,make_info line lline offset col strbef straft,Ast0.PLUS, - ref pos) + (str,Ast0.NONE,make_info line lline offset col strbef straft, + Ast0.PLUS(Ast.ONE),ref pos,-1) + | (Data.PLUSPLUS,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.NONE,make_info line lline offset col strbef straft, + Ast0.PLUS(Ast.MANY),ref pos,-1) | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.NONE,make_info line lline offset col strbef straft, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), - ref pos) + ref pos,-1) | (Data.OPT,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.OPT,make_info line lline offset col strbef straft, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), - ref pos) + ref pos,-1) | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) -> (str,Ast0.UNIQUE,make_info line lline offset col strbef straft, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), - ref pos) + ref pos,-1) let id2name (name, clt) = name let id2clt (name, clt) = clt @@ -166,7 +195,7 @@ let ty_pointerify ty m = (* Left is <=>, Right is =>. Collect <=>s. *) (* The parser should have done this, with precedences. But whatever... *) -let iso_adjust fn first rest = +let iso_adjust first_fn fn first rest = let rec loop = function [] -> [[]] | (Common.Left x)::rest -> @@ -178,10 +207,10 @@ let iso_adjust fn first rest = front::after -> []::(fn x::front)::after | _ -> failwith "not possible") in match loop rest with - front::after -> (fn first::front)::after + front::after -> (first_fn first::front)::after | _ -> failwith "not possible" -let check_meta tok = +let check_meta_tyopt type_irrelevant tok = let lookup rule name = try let info = Hashtbl.find Data.all_metadecls rule in @@ -199,7 +228,7 @@ let check_meta tok = raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) - | Ast.MetaFreshIdDecl(Ast.NONE,(rule,name)) -> + | Ast.MetaFreshIdDecl((rule,name),seed) -> raise (Semantic_cocci.Semantic "can't inherit the freshness of an identifier") @@ -247,21 +276,21 @@ let check_meta tok = ("incompatible inheritance declaration "^name))) | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) -> (match lookup rule name with - Ast.MetaExpDecl(_,_,ty1) when ty = ty1 -> () + Ast.MetaExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () | _ -> raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) -> (match lookup rule name with - Ast.MetaIdExpDecl(_,_,ty1) when ty = ty1 -> () + Ast.MetaIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () | _ -> raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) -> (match lookup rule name with - Ast.MetaLocalIdExpDecl(_,_,ty1) when ty = ty1 -> () + Ast.MetaLocalIdExpDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () | _ -> raise (Semantic_cocci.Semantic @@ -304,7 +333,7 @@ let check_meta tok = ("incompatible inheritance declaration "^name))) | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) -> (match lookup rule name with - Ast.MetaConstDecl(_,_,ty1) when ty = ty1 -> () + Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () | _ -> raise (Semantic_cocci.Semantic @@ -325,6 +354,16 @@ let check_meta tok = raise (Semantic_cocci.Semantic ("arity not allowed on imported declaration")) +let check_meta m = check_meta_tyopt false m + +let check_inherited_constraint meta_name fn = + match meta_name with + (None,_) -> failwith "constraint must be an inherited variable" + | (Some rule,name) -> + let i = (rule,name) in + check_meta_tyopt true (fn i); + i + let create_metadec ar ispure kindfn ids current_rule = List.concat (List.map @@ -338,17 +377,39 @@ let create_metadec ar ispure kindfn ids current_rule = kindfn ar rule ispure checker) ids) -let create_metadec_ne ar ispure kindfn ids current_rule = + +let create_metadec_virt ar ispure kindfn ids current_rule = List.concat (List.map - (function ((rule,nm),constraints) -> + (function nm -> + let checker = function x -> [Common.Right x] in + kindfn ar nm ispure checker !Flag.defined_virtual_env) + ids) + +let create_fresh_metadec kindfn ids current_rule = + List.concat + (List.map + (function ((rule,nm),seed) -> let (rule,checker) = match rule with None -> ((current_rule,nm),function x -> [Common.Left x]) | Some rule -> ((rule,nm), function x -> check_meta x; [Common.Right x]) in - kindfn ar rule ispure checker constraints) + kindfn rule checker seed) + ids) + +let create_metadec_with_constraints ar ispure kindfn ids current_rule = + List.concat + (List.map + (function ((rule,nm),constraints) -> + let (rule,checker) = + match rule with + None -> ((current_rule,nm),function x -> [Common.Left x]) + | Some rule -> + ((rule,nm), + function x -> check_meta x; [Common.Right x]) in + kindfn ar rule ispure checker constraints) ids) let create_metadec_ty ar ispure kindfn ids current_rule = @@ -423,9 +484,15 @@ let iterator i lp e rp s = Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s, (Ast0.default_info(),Ast0.context_befaft()))) -let switch s lp e rp lb c rb = +let switch s lp e rp lb d c rb = + let d = + List.map + (function d -> + Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),d))) + d in Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e, clt2mcode ")" rp,clt2mcode "{" lb, + Ast0.wrap(Ast0.DOTS(d)), Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb)) let ret_exp r e pv = @@ -479,4 +546,39 @@ let make_generated_rule_name_result nm d i a e ee = let make_script_rule_name_result lang deps = let l = id2name lang in - Ast.ScriptRulename (l,deps) + Ast.ScriptRulename (l,deps) + +let make_initial_script_rule_name_result lang deps = + let l = id2name lang in + Ast.InitialScriptRulename(l,deps) + +let make_final_script_rule_name_result lang deps = + let l = id2name lang in + Ast.FinalScriptRulename(l,deps) + +(* Allows type alone only when it is void and only when there is only one + parameter. This avoids ambiguity problems in the parser. *) +let verify_parameter_declarations = function + [] -> () + | [x] -> + (match Ast0.unwrap x with + Ast0.Param(t, None) -> + (match Ast0.unwrap t with + Ast0.BaseType(Ast.VoidType,_) -> () + | _ -> + failwith + (Printf.sprintf + "%d: only void can be a parameter without an identifier" + (Ast0.get_line t))) + | _ -> ()) + | l -> + List.iter + (function x -> + match Ast0.unwrap x with + Ast0.Param(t, None) -> + failwith + (Printf.sprintf + "%d: only void alone can be a parameter without an identifier" + (Ast0.get_line t)) + | _ -> ()) + l