Release coccinelle-0.2.2-rc1
[bpt/coccinelle.git] / parsing_cocci / parse_aux.ml
index 1190521..891a0af 100644 (file)
@@ -1,23 +1,23 @@
 (*
-* 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 <http://www.gnu.org/licenses/>.
-* 
-* 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 <http://www.gnu.org/licenses/>.
+ *
+ * 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 +30,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 +58,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 +173,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,7 +185,7 @@ 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 =
@@ -199,7 +206,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")
@@ -217,6 +224,13 @@ let check_meta tok =
          raise
            (Semantic_cocci.Semantic
               ("incompatible inheritance declaration "^name)))
+  | Ast.MetaInitDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaInitDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
   | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
       (match lookup rule name with
        Ast.MetaParamDecl(_,_) -> ()
@@ -331,17 +345,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 =
@@ -416,9 +452,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 =
@@ -472,4 +514,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