Coccinelle release 1.0.0-rc15
[bpt/coccinelle.git] / parsing_cocci / type_infer.ml
index 51e6ebe..8a2b4b7 100644 (file)
@@ -1,5 +1,7 @@
 (*
- * Copyright 2010, INRIA, University of Copenhagen
+ * 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
@@ -22,6 +24,7 @@
  *)
 
 
+# 0 "./type_infer.ml"
 module T = Type_cocci
 module Ast = Ast_cocci
 module Ast0 = Ast0_cocci
@@ -45,6 +48,7 @@ let err wrapped ty s =
 type id = Id of string | Meta of Ast.meta_name
 
 let int_type = T.BaseType(T.IntType)
+let void_type = T.BaseType(T.VoidType)
 let bool_type = T.BaseType(T.BoolType)
 let char_type = T.BaseType(T.CharType)
 let float_type = T.BaseType(T.FloatType)
@@ -104,7 +108,7 @@ let rec propagate_types env =
       Ast0.Id(id) ->
        (try Some(List.assoc (Id(Ast0.unwrap_mcode id)) env)
        with Not_found -> None)
-    | Ast0.MetaId(id,_,_) ->
+    | Ast0.MetaId(id,_,_,_) ->
        (try Some(List.assoc (Meta(Ast0.unwrap_mcode id)) env)
        with Not_found -> None)
     | Ast0.DisjId(_,id_list,_,_) ->
@@ -115,6 +119,7 @@ let rec propagate_types env =
        | Some t ->
            List.iter (function i -> Ast0.set_type i (Some t)) id_list;
            Some t)
+    | Ast0.AsIdent _ -> failwith "not possible"
     | _ -> k i in
 
   let strip_cv = function
@@ -126,6 +131,7 @@ let rec propagate_types env =
       T.BaseType(T.IntType)
     | T.BaseType(T.LongType)
     | T.BaseType(T.ShortType)
+    | T.BaseType(T.SizeType)
     | T.MetaType(_,_,_)
     | T.TypeName _
     | T.EnumName _
@@ -164,6 +170,7 @@ let rec propagate_types env =
        | Ast0.Assignment(exp1,op,exp2,_) ->
            let ty = lub_type (Ast0.get_type exp1) (Ast0.get_type exp2) in
              Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty
+       | Ast0.Sequence(exp1,op,exp2) -> Ast0.get_type exp2
        | Ast0.CondExpr(exp1,why,Some exp2,colon,exp3) ->
            let ty = lub_type (Ast0.get_type exp2) (Ast0.get_type exp3) in
              Ast0.set_type exp2 ty; Ast0.set_type exp3 ty; ty
@@ -176,6 +183,7 @@ let rec propagate_types env =
                   (match Ast0.get_type exp with
                        None -> Some (T.Pointer(T.Unknown))
                      | Some t -> Some (T.Pointer(t)))
+              | Ast.GetRefLabel -> Some (T.Pointer(void_type))
               | Ast.DeRef ->
                   (match Ast0.get_type exp with
                        Some (T.Pointer(t)) -> Some t
@@ -252,6 +260,7 @@ let rec propagate_types env =
        | Ast0.SizeOfExpr(szf,exp) -> Some(int_type)
        | Ast0.SizeOfType(szf,lp,ty,rp) -> Some(int_type)
        | Ast0.TypeExp(ty) -> None
+       | Ast0.Constructor(lp,ty,rp,init) -> Some(Ast0.ast0_type_to_type ty)
        | Ast0.MetaErr(name,_,_) -> None
        | Ast0.MetaExpr(name,_,Some [ty],_,_) -> Some ty
        | Ast0.MetaExpr(name,_,ty,_,_) -> None
@@ -276,19 +285,21 @@ let rec propagate_types env =
        | Ast0.Estars(_,Some e) ->
            let _ = r.VT0.combiner_rec_expression e in None
        | Ast0.OptExp(exp) -> Ast0.get_type exp
-       | Ast0.UniqueExp(exp) -> Ast0.get_type exp in
+       | Ast0.UniqueExp(exp) -> Ast0.get_type exp
+       | Ast0.AsExpr _ -> failwith "not possible" in
       Ast0.set_type e ty;
       ty in
 
   let rec strip id =
     match Ast0.unwrap id with
       Ast0.Id(name)                -> [Id(Ast0.unwrap_mcode name)]
-    | Ast0.MetaId(name,_,_)        -> [Meta(Ast0.unwrap_mcode name)]
+    | Ast0.MetaId(name,_,_,_)      -> [Meta(Ast0.unwrap_mcode name)]
     | Ast0.MetaFunc(name,_,_)      -> [Meta(Ast0.unwrap_mcode name)]
     | Ast0.MetaLocalFunc(name,_,_) -> [Meta(Ast0.unwrap_mcode name)]
     | Ast0.DisjId(_,id_list,_,_)   -> List.concat (List.map strip id_list)
     | Ast0.OptIdent(id)            -> strip id
-    | Ast0.UniqueIdent(id)         -> strip id in
+    | Ast0.UniqueIdent(id)         -> strip id
+    | Ast0.AsIdent _ -> failwith "not possible" in
 
   let process_whencode notfn allfn exp = function
       Ast0.WhenNot(x) -> let _ = notfn x in ()
@@ -327,16 +338,19 @@ let rec propagate_types env =
 
   and process_decl env decl =
     match Ast0.unwrap decl with
-      Ast0.MetaDecl(_,_) | Ast0.MetaField(_,_) -> []
+      Ast0.MetaDecl(_,_) | Ast0.MetaField(_,_)
+    | Ast0.MetaFieldList(_,_,_) -> []
     | Ast0.Init(_,ty,id,_,exp,_) ->
-       let _ =
-         (propagate_types env).VT0.combiner_rec_initialiser exp in
+       let _ = (propagate_types env).VT0.combiner_rec_initialiser exp in
        let ty = Ast0.ast0_type_to_type ty in
        List.map (function i -> (i,ty)) (strip id)
     | Ast0.UnInit(_,ty,id,_) ->
        let ty = Ast0.ast0_type_to_type ty in
        List.map (function i -> (i,ty)) (strip id)
     | Ast0.MacroDecl(_,_,_,_,_) -> []
+    | Ast0.MacroDeclInit(_,_,_,_,_,exp,_) ->
+        let _ = (propagate_types env).VT0.combiner_rec_initialiser exp in
+       []
     | Ast0.TyDecl(ty,_) -> []
               (* pad: should handle typedef one day and add a binding *)
     | Ast0.Typedef(_,_,_,_) -> []
@@ -344,7 +358,8 @@ let rec propagate_types env =
        List.concat(List.map (process_decl env) disjs)
     | Ast0.Ddots(_,_) -> [] (* not in a statement list anyway *)
     | Ast0.OptDecl(decl) -> process_decl env decl
-    | Ast0.UniqueDecl(decl) -> process_decl env decl in
+    | Ast0.UniqueDecl(decl) -> process_decl env decl
+    | Ast0.AsDecl _ -> failwith "not possible" in
 
   let statement_dots r k d =
     match Ast0.unwrap d with
@@ -382,11 +397,25 @@ let rec propagate_types env =
        let fenv = List.concat (List.map get_binding (Ast0.undots params)) in
        (propagate_types (fenv@env)).VT0.combiner_rec_statement_dots body
     | Ast0.IfThen(_,_,exp,_,_,_) | Ast0.IfThenElse(_,_,exp,_,_,_,_,_)
-    | Ast0.While(_,_,exp,_,_,_) | Ast0.Do(_,_,_,_,exp,_,_)
-    | Ast0.For(_,_,_,_,Some exp,_,_,_,_,_) ->
+    | Ast0.While(_,_,exp,_,_,_) | Ast0.Do(_,_,_,_,exp,_,_) ->
        let _ = k s in
-       post_bool exp;
-       None
+        post_bool exp;
+        None
+    | Ast0.For(a,b,first,exp,c,d,e,f,g) ->
+       (match Ast0.unwrap first with
+         Ast0.ForExp _ ->
+           (match exp with
+             Some exp ->
+               let _ = k s in
+               post_bool exp;
+               None
+           | None -> k s)
+       | Ast0.ForDecl (_,decl) ->
+       (* not super elegant..., reuses a ; (d) *)
+           let newenv = (process_decl env decl)@env in
+           let dummy = Ast0.rewrap first (Ast0.ForExp (None,c)) in
+           (propagate_types newenv).VT0.combiner_rec_statement
+             (Ast0.rewrap s (Ast0.For(a,b,dummy,exp,c,d,e,f,g))))
     | Ast0.Switch(_,_,exp,_,_,decls,cases,_) ->
        let senv = process_statement_list r env (Ast0.undots decls) in
        let res =