let translate_C_expr_to_term ?(cast=true) expr =
(* if cast is true, the term should have the type of expr (which is a C type) *)
(* otherwise, the term should have type integer
(or real if the C type of expr if not a subtype of integer: TODO) *)
let e_typ = Cil.typeOf expr in
let aterm = Logic_utils.expr_to_term ~cast:false expr in
let term =
if cast then
begin
(* expr_to_term_with_cast expr *)
(* not used since it adds casts everywhere (not pretty):
since sub-expressions are also checked for annotation,
might as well cast only top expression *)
match aterm.term_node with
| TCastE(_,_) -> (* no point in recasting *) aterm
| TConst _ -> (* constants are not cast,
though in some cases they should (big const) *) aterm
| TLval _ -> aterm
| _ ->
if (Cil.isIntegralType e_typ || Cil.isFloatingType e_typ)
then
Logic_const.term
(TCastE
(e_typ,
Logic_const.term
aterm.term_node
(Logic_utils.typ_to_logic_type e_typ))) (Ctype e_typ)
else aterm
end
else aterm
in
(*
debug ~level:2
"input expr: %a (%a)\n" Cil.d_exp expr Cil.d_type (Cil.typeOf expr)
;
let t1,t2 = expr_to_term ~cast:false expr, expr_to_term ~cast:true expr
in
debug ~level:2
"output integer term: %a (%a)\n" Cil.d_term t1 Cil.d_logic_type t1.term_type
;
debug ~level:2
"output (C cast) term: %a (%a)\n" Cil.d_term t2 Cil.d_logic_type t2.term_type
;
*)
term