X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/785a3008ddade80f642257bb47d43158ac8b8311..17ba07880e1838028b4516ba7a2db2147b3aa1c9:/parsing_cocci/parse_aux.ml diff --git a/parsing_cocci/parse_aux.ml b/parsing_cocci/parse_aux.ml index 31cb8e9..6f300f3 100644 --- a/parsing_cocci/parse_aux.ml +++ b/parsing_cocci/parse_aux.ml @@ -1,9 +1,37 @@ +(* + * Copyright 2012, INRIA + * Julia Lawall, Gilles Muller + * Copyright 2010-2011, INRIA, University of Copenhagen + * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix + * Copyright 2005-2009, 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 *) module Ast0 = Ast0_cocci module Ast = Ast_cocci (* types for metavariable tokens *) type info = Ast.meta_name * Ast0.pure * Data.clt +type midinfo = + Ast.meta_name * Data.iconstraints * Ast.seed * Ast0.pure * Data.clt 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 @@ -17,7 +45,7 @@ let get_option fn = function None -> None | Some x -> Some (fn x) -let make_info line logical_line offset col strbef straft = +let make_info line logical_line offset col strbef straft isSymbol = let new_pos_info = {Ast0.line_start = line; Ast0.line_end = line; Ast0.logical_start = logical_line; Ast0.logical_end = logical_line; @@ -25,10 +53,11 @@ let make_info line logical_line offset col strbef straft = { Ast0.pos_info = new_pos_info; Ast0.attachable_start = true; Ast0.attachable_end = true; Ast0.mcode_start = []; Ast0.mcode_end = []; - Ast0.strings_before = strbef; Ast0.strings_after = straft; } + Ast0.strings_before = strbef; Ast0.strings_after = straft; + Ast0.isSymbolIdent = isSymbol; } let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) = - make_info line logical_line offset col strbef straft + make_info line logical_line offset col strbef straft false let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) = (arity,line,lline,offset,col,[],straft,pos) @@ -36,44 +65,52 @@ 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) +(* used for #define, to put aft on ident/( *) +let get_aft (arity,line,lline,offset,col,strbef,straft,pos) = straft + +let set_aft aft (arity,line,lline,offset,col,strbef,_,pos) = + (arity,line,lline,offset,col,strbef,aft,pos) + let drop_pos (arity,line,lline,offset,col,strbef,straft,pos) = - (arity,line,lline,offset,col,strbef,straft,Ast0.NoMetaPos) + (arity,line,lline,offset,col,strbef,straft,[]) -let clt2mcode str = function +let clt2mcode_ext str isSymbol = 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,-1) + (str,Ast0.NONE,make_info line lline offset col strbef straft isSymbol, + Ast0.MINUS(ref(Ast.NOREPLACEMENT,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,-1) + (str,Ast0.OPT,make_info line lline offset col strbef straft isSymbol, + Ast0.MINUS(ref(Ast.NOREPLACEMENT,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,-1) + (str,Ast0.UNIQUE,make_info line lline offset col strbef straft isSymbol, + Ast0.MINUS(ref(Ast.NOREPLACEMENT,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, + (str,Ast0.NONE,make_info line lline offset col strbef straft isSymbol, 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, + (str,Ast0.NONE,make_info line lline offset col strbef straft isSymbol, 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, + (str,Ast0.NONE,make_info line lline offset col strbef straft isSymbol, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), ref pos,-1) | (Data.OPT,line,lline,offset,col,strbef,straft,pos) -> - (str,Ast0.OPT,make_info line lline offset col strbef straft, + (str,Ast0.OPT,make_info line lline offset col strbef straft isSymbol, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), ref pos,-1) | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) -> - (str,Ast0.UNIQUE,make_info line lline offset col strbef straft, + (str,Ast0.UNIQUE,make_info line lline offset col strbef straft isSymbol, Ast0.CONTEXT(ref(Ast.NOTHING, Ast0.default_token_info,Ast0.default_token_info)), ref pos,-1) +let clt2mcode name clt = clt2mcode_ext name false clt let id2name (name, clt) = name let id2clt (name, clt) = clt let id2mcode (name, clt) = clt2mcode name clt +let sym2mcode (name, clt) = clt2mcode_ext name true clt let mkdots str (dot,whencode) = match str with @@ -106,6 +143,11 @@ let mkddots str (dot,whencode) = | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w)) | _ -> failwith "cannot happen" +let mkddots_one str (dot,whencode) = + match str with + "..." -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, whencode)) + | _ -> failwith "cannot happen" + let mkpdots str dot = match str with "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot)) @@ -149,6 +191,13 @@ let ty_pointerify ty m = (function inner -> function cur -> Type_cocci.Pointer(inner)) ty m +let arrayify ty ar = + List.fold_right + (function (l,i,r) -> + function rest -> + Ast0.wrap (Ast0.Array(rest,clt2mcode "[" l,i,clt2mcode "]" r))) + ar ty + (* Left is <=>, Right is =>. Collect <=>s. *) (* The parser should have done this, with precedences. But whatever... *) let iso_adjust first_fn fn first rest = @@ -176,7 +225,14 @@ let lookup rule name = (Semantic_cocci.Semantic("bad rule "^rule^" or bad variable "^name)) let check_meta_tyopt type_irrelevant = function - Ast.MetaIdDecl(Ast.NONE,(rule,name)) -> + Ast.MetaMetaDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaMetaDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaIdDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> () | _ -> @@ -187,23 +243,30 @@ let check_meta_tyopt type_irrelevant = function raise (Semantic_cocci.Semantic "can't inherit the freshness of an identifier") - | Ast.MetaListlenDecl((rule,name)) -> + | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with - Ast.MetaListlenDecl(_) -> () + Ast.MetaTypeDecl(_,_) -> () | _ -> raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) - | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) -> + | Ast.MetaInitDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with - Ast.MetaTypeDecl(_,_) -> () + Ast.MetaInitDecl(_,_) -> () | _ -> raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) - | Ast.MetaInitDecl(Ast.NONE,(rule,name)) -> + | Ast.MetaInitListDecl(Ast.NONE,(rule,name),len_name) -> (match lookup rule name with - Ast.MetaInitDecl(_,_) -> () + Ast.MetaInitListDecl(_,_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaListlenDecl((rule,name)) -> + (match lookup rule name with + Ast.MetaListlenDecl(_) -> () | _ -> raise (Semantic_cocci.Semantic @@ -222,6 +285,13 @@ let check_meta_tyopt type_irrelevant = function raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) + | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) -> + (match lookup rule name with + Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) | Ast.MetaErrDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with Ast.MetaErrDecl(_,_) -> () @@ -258,6 +328,27 @@ let check_meta_tyopt type_irrelevant = function raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) + | Ast.MetaDeclDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaDeclDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaFieldDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaFieldDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaFieldListDecl(Ast.NONE,(rule,name),len_name) -> + (match lookup rule name with + Ast.MetaFieldListDecl(_,_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) | Ast.MetaStmDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with Ast.MetaStmDecl(_,_) -> () @@ -286,17 +377,11 @@ let check_meta_tyopt type_irrelevant = function raise (Semantic_cocci.Semantic ("incompatible inheritance declaration "^name))) - | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) -> - (match lookup rule name with - Ast.MetaConstDecl(_,_,ty1) when type_irrelevant or ty = ty1 -> () - | _ -> - raise - (Semantic_cocci.Semantic - ("incompatible inheritance declaration "^name))) | Ast.MetaPosDecl(Ast.NONE,(rule,name)) -> (match lookup rule name with Ast.MetaPosDecl(_,_) -> - if not (List.mem rule !Data.inheritable_positions) + if not (List.mem rule !Data.inheritable_positions) && + not !Data.ignore_patch_or_match then raise (Semantic_cocci.Semantic @@ -414,6 +499,15 @@ let meta_field name = let (nm,pure,clt) = name in Ast0.wrap(Ast0.MetaField(clt2mcode nm clt,pure)) +let meta_field_list name = + let (nm,lenname,pure,clt) = name in + let lenname = + match lenname with + Ast.AnyLen -> Ast0.AnyListLen + | Ast.MetaLen nm -> Ast0.MetaListLen(clt2mcode nm clt) + | Ast.CstLen n -> Ast0.CstListLen n in + Ast0.wrap(Ast0.MetaFieldList(clt2mcode nm clt,lenname,pure)) + let meta_stm name = let (nm,pure,clt) = name in Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure)) @@ -501,23 +595,44 @@ let make_iso_rule_name_result n = Ast.CocciRulename (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*)) +let fix_dependencies d = + let rec loop inverted = function + Ast0.Dep s when inverted -> Ast.AntiDep s + | Ast0.Dep s -> Ast.Dep s + | Ast0.AntiDep d -> loop (not inverted) d + | Ast0.EverDep s when inverted -> Ast.NeverDep s + | Ast0.EverDep s -> Ast.EverDep s + | Ast0.NeverDep s when inverted -> Ast.EverDep s + | Ast0.NeverDep s -> Ast.NeverDep s + | Ast0.AndDep(d1,d2) when inverted -> + Ast.OrDep(loop inverted d1,loop inverted d2) + | Ast0.AndDep(d1,d2) -> + Ast.AndDep(loop inverted d1,loop inverted d2) + | Ast0.OrDep(d1,d2) when inverted -> + Ast.AndDep(loop inverted d1,loop inverted d2) + | Ast0.OrDep(d1,d2) -> + Ast.OrDep(loop inverted d1,loop inverted d2) + | Ast0.NoDep -> Ast.NoDep + | Ast0.FailDep -> Ast.FailDep in + loop false d + let make_cocci_rule_name_result nm d i a e ee = - Ast.CocciRulename (check_rule_name nm,d,i,a,e,ee) + Ast.CocciRulename (check_rule_name nm,fix_dependencies d,i,a,e,ee) let make_generated_rule_name_result nm d i a e ee = - Ast.GeneratedRulename (check_rule_name nm,d,i,a,e,ee) + Ast.GeneratedRulename (check_rule_name nm,fix_dependencies d,i,a,e,ee) let make_script_rule_name_result lang nm deps = let l = id2name lang in - Ast.ScriptRulename (check_rule_name nm,l,deps) + Ast.ScriptRulename (check_rule_name nm,l,fix_dependencies deps) let make_initial_script_rule_name_result lang deps = let l = id2name lang in - Ast.InitialScriptRulename(None,l,deps) + Ast.InitialScriptRulename(None,l,fix_dependencies deps) let make_final_script_rule_name_result lang deps = let l = id2name lang in - Ast.FinalScriptRulename(None,l,deps) + Ast.FinalScriptRulename(None,l,fix_dependencies deps) (* Allows type alone only when it is void and only when there is only one parameter. This avoids ambiguity problems in the parser. *) @@ -545,3 +660,30 @@ let verify_parameter_declarations = function (Ast0.get_line t)) | _ -> ()) l + +(* ---------------------------------------------------------------------- *) +(* decide whether an init list is ordered or unordered *) + +let struct_initializer initlist = + let rec loop i = + match Ast0.unwrap i with + Ast0.InitGccExt _ -> true + | Ast0.InitGccName _ -> true + | Ast0.OptIni i | Ast0.UniqueIni i -> loop i + | Ast0.MetaInit _ | Ast0.MetaInitList _ -> false (* ambiguous... *) + | _ -> false in + let l = Ast0.undots initlist in + (l = []) or (List.exists loop l) + +let drop_dot_commas initlist = + match Ast0.unwrap initlist with + Ast0.DOTS(l) -> + let rec loop after_comma = function + [] -> [] + | x::xs -> + (match Ast0.unwrap x with + Ast0.Idots(dots,whencode) -> x :: (loop true xs) + | Ast0.IComma(comma) when after_comma -> (*drop*) loop false xs + | _ -> x :: (loop false xs)) in + Ast0.rewrap initlist (Ast0.DOTS(loop false l)) + | _ -> failwith "not supported"