123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116(**************************************************************************)(* *)(* This file is part of the Frama-C's Lannotate plug-in. *)(* *)(* Copyright (C) 2012-2025 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file LICENSE) *)(* *)(**************************************************************************)openCil_typesletunk_loc=Cil_datatype.Location.unknownmoduleExp_builder=structletmk?(loc=unk_loc)=Cil.new_exp~locletzero?(loc=unk_loc)()=Cil.zero~locletone?(loc=unk_loc)()=Cil.one~locletinteger?(loc=unk_loc)=Cil.integer~locletkinteger?(loc=unk_loc)=Cil.kinteger~locletkinteger64?(loc=unk_loc)kind=Cil.kinteger64~loc~kindletfloat?(loc=unk_loc)=Cil.kfloat~locFDoubleletstring?(loc=unk_loc)=Cil.mkString~locletvar?(loc=unk_loc)varinfo=Cil.evar~locvarinfoletlval?(loc=Cil_datatype.Location.unknown)lval=Cil.new_exp~loc(Lvallval)letmem?(loc=unk_loc)addroff=Cil.new_exp~loc(Lval(Cil.mkMem~addr~off))letlnot?(loc=unk_loc)e=Cil.new_exp~loc(UnOp(LNot,e,Cil_const.intType))letneg?(loc=unk_loc)e=letoldt=Cil.typeOfeinletnewt=Cil.integralPromotionoldtin(* make integral promotion explicit *)lete'=Cil.mkCastT~oldt~newteinCil.new_exp~loc(UnOp(Neg,e',newt))letbinop?(loc=unk_loc)opleftright=Cil.mkBinOp~locopleftrightletimplies?(loc=unk_loc)lr=letn_l=lnot~loclinCil.mkBinOp~locLOrn_lrletiff?(loc=unk_loc)lr=letl_imp_r=implies~loclrinletr_imp_l=implies~locrlinCil.mkBinOp~locLAndl_imp_rr_imp_lletniff?(loc=unk_loc)lr=letnl_and_r=Cil.mkBinOp~locLAnd(lnot~locl)rinletl_and_nr=Cil.mkBinOp~locLAndl(lnot~locr)inCil.mkBinOp~locLOrnl_and_rl_and_nrletrecreplace~whole~part~(repl:exp):exp=ifpart==wholethenreplelsematchwhole.enodewith|UnOp(op,e,typ)->lete'=replace~whole:e~part~replinife==e'thenwholeelsemk~loc:whole.eloc(UnOp(op,e',typ))|BinOp(op,e1,e2,typ)->lete1'=replace~whole:e1~part~replinlete2'=replace~whole:e2~part~replinife1==e1'&&e2==e2'thenwholeelsemk~loc:whole.eloc(BinOp(op,e1',e2',typ))|_->whole(** Joins some expressions (at least one) with a binary operator. *)letrev_join?(loc=Cil_datatype.Location.unknown)opl=matchlwith|[]->invalid_arg"join"|head::tail->List.fold_left(funacce->Cil.mkBinOp~locopeacc)headtailletjoin?(loc=Cil_datatype.Location.unknown)opl=rev_join~locop(List.revl)endmoduleStmt_builder=structletmk=Cil.mkStmt~valid_sid:trueletinstr=Cil.mkStmtOneInstr~valid_sid:trueletblockstmts=mk(Block(Cil.mkBlockstmts))end