let rec expr mem e =
match (Cil.stripInfo e).enode with
| Info _ -> WpLog.fatal "non translation for info type expression"
| Const (cnst) -> expr_const mem cnst
| CastE (ty,e) ->
if Cil.isPointerType ty && Cil.isZero e then
(let t = Ctypes.object_of_pointed (Ctypes.object_of ty) in
M.V_pointer(t, M.null))
else
expr_cast (Cil.typeOf e) ty (expr mem e)
| BinOp (op, e1, e2, ty) ->
expr_binop mem op ty
e1 (Cil.typeOf e1)
e2 (Cil.typeOf e2)
| UnOp (op, e1, ty) ->
expr_unop mem op ty e1 (Cil.typeOf e1)
| Lval lval ->
let t = Cil.typeOf e in
let l = addr mem lval in
M.load mem (Ctypes.object_of t) l
| StartOf lval ->
let ty_elt =
Ctypes.object_of_pointed (Ctypes.object_of (Cil.typeOf e)) in
M.V_pointer(ty_elt,startof mem ty_elt lval)
| AddrOf lval ->
let ty_elt =
Ctypes.object_of_pointed (Ctypes.object_of (Cil.typeOf e))
in
M.V_pointer(ty_elt,addr mem lval)
| AlignOfE _ | AlignOf _
| SizeOfE _ | SizeOf _ | SizeOfStr _ ->
let e' = Cil.constFold true e in
match e'.enode with
| Const _ -> expr mem e'
| _ ->
WpLog.not_yet_implemented "sizeof(%a)"
!Ast_printer.d_exp e