let rec vardata2type dv = 
  let rec data2type d =
  let str = Pretty_utils.sfprintf "%a" pp_data2 d in
  match d with
    | E2addr v ->
        let t = match v.lv_type with
          | Ctype t -> TPtr (t, [])
          | _ -> abort "pointer to logic_type not implemented"
        in t
    | E2depl (_p, WpFol.Pfield f) -> TPtr (f.ftype, [])
    | E2depl (p, WpFol.Pidx _i) ->
        begin 
          try match Cil.unrollType (vardata2type p) with
          | TPtr (TArray (te, _, _, _), _) -> TPtr (te, [])
          | _ -> abort ("+(i) but not ptr on array: "^str)
          with Calculus.InvalidModel _ -> abort ("E2depl on exp <> data"^str)
        end
    | E2proj (_d, WpFol.Pfield f) -> f.ftype
    | E2proj (t, WpFol.Pidx _i) -> 
        begin
          try let tt = vardata2type t in  Types.ctype_array_elem tt
          with Calculus.InvalidModel _ -> abort  ("E2proj on exp <> data"^str)
        end
    | E2shift (p, _) -> 
        begin
        try vardata2type p 
        with Calculus.InvalidModel _ -> abort ("E2shift on exp <> data"^str)
        end
    | E2load (_, Fol.Tdata p) ->
        begin match Cil.unrollType (data2type p) with
          | TPtr (t, _) -> TPtr (t, [])
          | _ -> abort ("load but not a pointer"^str)
        end
    | E2load _ -> abort ("E2load on exp <> data"^str)
    | E2store _ -> abort "why do we need E2store type ???"
  in
  match dv with
    | Fol.Tdata d -> data2type d
    | Fol.Tvar v ->
        let t = match Fol.lvar_of_variable v with
          | None -> abort ""
          | Some lv ->  match lv.lv_type with
              | Ctype t -> t
              | _ -> abort ""
        in t
    | _ -> abort ""