123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112(**************************************************************************)(* *)(* 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_typesmoduleInstantiator_builder:sig(** Builds a [Instantiator] module (used by [Transform]) from a [Generator_sig] *)(** Signature for a new instantiator generator.
In order to support a new function, this module must be implemented and
registered to the [Transform] module.
*)moduletypeGenerator_sig=sig(** [Hashtbl] module used by the [Make_instantiator] module to generate the
function cache. The [key] ([override_key]) must identify a function
override.
*)moduleHashtbl:Datatype.Hashtbltypeoverride_key=Hashtbl.key(** Name of the implemented instantiator function *)valfunction_name:string(** [well_typed_call ret fct args] must return true if and only if the
corresponding call is well typed in the sens that the generator can
produce a function override for the corresponding return value and
parameters, according to their types and/or values.
*)valwell_typed_call:lvaloption->varinfo->explist->bool(** [key_from_call ret fct args] must return an identifier for the
corresponding call. [key_from_call ret1 fct1 args1] and
[key_from_call ret2 fct2 args2] must equal if and only if the same
override function can be used for both call. Any call for which
[well_typed_call] returns true must be able to give a key.
*)valkey_from_call:lvaloption->varinfo->explist->override_key(** [retype_args key args] must returns a new argument list compatible with
the function identified by [override_key]. [args] is the list of arguments
that were given to the call for with [Transform] is currently replacing.
Most of the time, it will consists in removing/changing some casts. But
note that arguments can be removed (for example if the override is built
because some constant have specialized).
*)valretype_args:override_key->explist->explist(** [args_for_original key args] must transform the list of parameters of the
override function such that the new list can be given to the original
function. For example, if for a call:
[foo(x, 0, z)]
The [Instantiator] module generates an override:
[void foo_spec(int p1, int p3);]
The received list of expression is [ p1 ; p3 ] and thus the returned list
should be [ p1 ; 0 ; p3 ] (so that the replaced call [foo_spec(x, z)] has
the same behavior).
Note that there is no need to introduce casts to the original type, it is
introduced by [Make_instantiator].
*)valargs_for_original:override_key->explist->explist(** [generate_prototype key] must generate the name and the type corresponding
to [key].
*)valgenerate_prototype:override_key->(string*typ)(** [generate_spec key loc fundec] must generate the specification of the
[fundec] generated from [key]. The location is the one generated by the
[Transform] visitor. Note that it must return a [funspec] but should
{b not} register it in [Annotations] tables.
*)valgenerate_spec:override_key->location->fundec->funspecendend=Instantiator_buildermoduleTransform:sig(** Registers a new [Instantiator] to the visitor from the [Generator_sig] module
of this instantiator. Each new instantiator function generator should call this
globally.
*)valregister:(moduleInstantiator_builder.Generator_sig)->unitend=TransformmoduleGlobal_context:sig(** [get_variable name f] searches for an existing variable [name]. If this
variable does not exists, it is created using [f].
The obtained varinfo does not need to be registered, nor [f] needs to
perform the registration, it will be done by the transformation.
*)valget_variable:string->(unit->varinfo)->varinfoend=Global_context