123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* 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 licenses/LGPLv2.1). *)(* *)(**************************************************************************)openCil_typesopenBasic_blocksmoduletypeGenerator_sig=sigmoduleHashtbl:Datatype.Hashtbltypeoverride_key=Hashtbl.keyvalfunction_name:stringvalwell_typed_call:lvaloption->varinfo->explist->boolvalkey_from_call:lvaloption->varinfo->explist->override_keyvalretype_args:override_key->explist->explistvalargs_for_original:override_key->explist->explistvalgenerate_prototype:override_key->(string*typ)valgenerate_spec:override_key->location->fundec->funspecendmoduletypeInstantiator=sigmoduleEnabled:Parameter_sig.Booltypeoverride_keyvalfunction_name:stringvalwell_typed_call:lvaloption->varinfo->explist->boolvalkey_from_call:lvaloption->varinfo->explist->override_keyvalretype_args:override_key->explist->explistvalget_override:override_key->fundecvalget_kfs:unit->kernel_functionlistvalclear:unit->unitendletbuild_bodycallercalleeargs_generator=letloc=Cil_datatype.Location.unknowninletret_var=matchCil.getReturnTypecaller.svar.vtypewith|twhenCil.isVoidTypet->None|t->Some(Cil.makeLocalVarcaller"__retres"t)inletcall=letargs=List.mapCil.evarcaller.sformalsinletargs=args_generatorargsinCil.mkStmt(Instr(call_function(Option.mapCil.varret_var)calleeargs))inletret=Cil.mkStmt(Return(Option.mapCil.evarret_var,loc))in{(Cil.mkBlock[call;ret])withblocals=Option.to_listret_var}moduleMake_instantiator(G:Generator_sig)=structincludeGmoduleEnabled=Options.NewInstantiator(G)moduleCache=structlettbl=G.Hashtbl.create13letfind=G.Hashtbl.findtblletadd=G.Hashtbl.addtblletfoldf=G.Hashtbl.foldftblletclear()=G.Hashtbl.cleartblendletmake_fundeckey=letopenGlobals.Functionsinlet(name,typ)=G.generate_prototypekeyinletfd=Basic_blocks.prepare_definitionnametypinletorig=get_vi(find_by_namefunction_name)inletsbody=build_bodyfdorig(G.args_for_originalkey)inletfd={fdwithsbody}inCfg.cfgFunfd;fdletbuild_functionkey=letloc=Cil_datatype.Location.unknowninletfd=make_fundeckeyinletspec=Cil.empty_funspec()inGlobals.Functions.replace_by_definitionspecfdloc;letkf=Globals.Functions.getfd.svarinletspec=generate_speckeylocfdinAnnotations.add_behaviorsOptions.emitterkfspec.spec_behavior;List.iter(Annotations.add_completeOptions.emitterkf)spec.spec_complete_behaviors;List.iter(Annotations.add_disjointOptions.emitterkf)spec.spec_disjoint_behaviors;fdletget_overridekey=tryCache.findkeywithNot_found->letfd=build_functionkeyinCache.addkeyfd;fd(* If you use this before finalization, you'll have problems *)letget_kfs()=Cache.fold(fun_fdl->Globals.Functions.getfd.svar::l)[]letclear()=Cache.clear()end