let rec ctype_of_data l = match l with
| F.D1null | F.D1base _ -> Cil.voidPtrType
| F.D1proj (_, F.Pfield f) -> f.ftype
| F.D1proj (l, F.Pidx _) -> Cil.typeOf_array_elem (ctype_of_data l)
| F.D1addr (vi,_) -> TPtr (vi.vtype, [])
| F.D1var (Some (vi, _), _) -> vi.vtype
| F.D1var (None,v) ->
let t = match F.ctype_of_fvar v with
| Some t -> t
| None -> unsupported "unknown type of %a" F.pp_var v
in t
| F.D1depl (_, F.Pfield f) -> TPtr (f.ftype, [])
| F.D1depl (l, F.Pidx _) ->
let t_addr_array = ctype_of_data l in
let t_array = Cil.typeOf_pointed t_addr_array in
let t_elem = Cil.typeOf_array_elem t_array in
TPtr (t_elem, [])
| F.D1indir (l) -> Cil.typeOf_pointed (ctype_of_data l)
| F.D1shift (l, _) -> ctype_of_data l
| F.D1mu (l, _, _) -> ctype_of_data l
| F.D1muRange (l, _) -> ctype_of_data l
| F.D1muI (l, _, _) -> ctype_of_data l
| F.D1muIrange (l, _) -> ctype_of_data l