module Annotations:sig..end
Annotations in the AST. The AST should be computed before calling functions of this module.
val code_annot : ?emitter:Emitter.t ->
?filter:(Cil_types.code_annotation -> bool) ->
Cil_types.stmt -> Cil_types.code_annotation listGet all the code annotations attached to the given statement.
If emitter (resp. filter) is specified, return only the annotations that
has been generated by this emitter (resp. that satisfies the given
predicate).
val code_annot_emitter : ?filter:(Emitter.t -> Cil_types.code_annotation -> bool) ->
Cil_types.stmt -> (Cil_types.code_annotation * Emitter.t) listSame as Annotations.code_annot, but also returns the emitter who emitted the
annotation.
exception No_funspec of Emitter.t
val funspec : ?emitter:Emitter.t ->
?populate:bool -> Cil_types.kernel_function -> Cil_types.funspecGet the contract associated to the given function.
If emitter is specified, return only the annotations that
has been generated by this emitter. If populate is set to true
(default is true), then the default contract of function declaration is
generated.
No_funspec whenever the given function has no specificationval has_funspec : Cil_types.kernel_function -> booltrue iff the function has a non-empty specification.val behaviors : ?emitter:Emitter.t ->
?populate:bool -> Cil_types.kernel_function -> Cil_types.funbehavior listGet the behaviors clause of the contract associated to the given function.
Meaning of emitter and populate is similar to Annotations.funspec.
No_funspec whenever the given function has no specificationval decreases : ?emitter:Emitter.t ->
?populate:bool -> Cil_types.kernel_function -> Cil_types.variant optionIf any, get the decrease clause of the contract associated to the given
function. Meaning of emitter and populate is similar to Annotations.funspec.
No_funspec whenever the given function has no specificationval terminates : ?emitter:Emitter.t ->
?populate:bool ->
Cil_types.kernel_function -> Cil_types.identified_predicate optionIf any, get the terminates clause of the contract associated to the given
function. Meaning of emitter and populate is similar to Annotations.funspec.
No_funspec whenever the given function has no specificationval complete : ?emitter:Emitter.t ->
?populate:bool -> Cil_types.kernel_function -> string list listGet the complete behaviors clause of the contract associated to the given
function. Meaning of emitter and populate is similar to Annotations.funspec.
No_funspec whenever the given function has no specificationval disjoint : ?emitter:Emitter.t ->
?populate:bool -> Cil_types.kernel_function -> string list listIf any, get the disjoint behavior clause of the contract associated to the
given function. Meaning of emitter and populate is similar to
Annotations.funspec.
No_funspec whenever the given function has no specificationval model_fields : ?emitter:Emitter.t -> Cil_types.typ -> Cil_types.model_info listreturns the model fields attached to a given type (either directly or because the type is a typedef of something that has model fields.
val iter_code_annot : (Emitter.t -> Cil_types.code_annotation -> unit) -> Cil_types.stmt -> unitIter on each code annotation attached to the given statement.
val fold_code_annot : (Emitter.t -> Cil_types.code_annotation -> 'a -> 'a) ->
Cil_types.stmt -> 'a -> 'aFold on each code annotation attached to the given statement.
val iter_all_code_annot : ?sorted:bool ->
(Cil_types.stmt -> Emitter.t -> Cil_types.code_annotation -> unit) -> unitIter on each code annotation of the program.
If sorted is true (the default), iteration is sorted according
to the location of the statements and by emitter. Note that the
sorted version is less efficient than the unsorted iteration.
val fold_all_code_annot : ?sorted:bool ->
(Cil_types.stmt -> Emitter.t -> Cil_types.code_annotation -> 'a -> 'a) ->
'a -> 'aFold on each code annotation of the program. See above for
the meaning of the sorted argument.
val iter_global : (Emitter.t -> Cil_types.global_annotation -> unit) -> unitIter on each global annotation of the program.
val fold_global : (Emitter.t -> Cil_types.global_annotation -> 'a -> 'a) -> 'a -> 'aFold on each global annotation of the program.
val iter_requires : (Emitter.t -> Cil_types.identified_predicate -> unit) ->
Cil_types.kernel_function -> string -> unitIter on the requires of the corresponding behavior.
val fold_requires : (Emitter.t -> Cil_types.identified_predicate -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'aFold on the requires of the corresponding behavior.
val iter_assumes : (Emitter.t -> Cil_types.identified_predicate -> unit) ->
Cil_types.kernel_function -> string -> unitIter on the assumes of the corresponding behavior.
val fold_assumes : (Emitter.t -> Cil_types.identified_predicate -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'aFold on the assumes of the corresponding behavior.
val iter_ensures : (Emitter.t ->
Cil_types.termination_kind * Cil_types.identified_predicate -> unit) ->
Cil_types.kernel_function -> string -> unitIter on the ensures of the corresponding behavior.
val fold_ensures : (Emitter.t ->
Cil_types.termination_kind * Cil_types.identified_predicate -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'aFold on the ensures of the corresponding behavior.
val iter_assigns : (Emitter.t -> Cil_types.assigns -> unit) ->
Cil_types.kernel_function -> string -> unitIter on the assigns of the corresponding behavior.
val fold_assigns : (Emitter.t -> Cil_types.assigns -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'aFold on the assigns of the corresponding behavior.
val iter_allocates : (Emitter.t -> Cil_types.allocation -> unit) ->
Cil_types.kernel_function -> string -> unitIter on the allocates of the corresponding behavior.
val fold_allocates : (Emitter.t -> Cil_types.allocation -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'aFold on the allocates of the corresponding behavior.
val iter_extended : (Emitter.t -> Cil_types.acsl_extension -> unit) ->
Cil_types.kernel_function -> string -> unitval fold_extended : (Emitter.t -> Cil_types.acsl_extension -> 'a -> 'a) ->
Cil_types.kernel_function -> string -> 'a -> 'a
val iter_behaviors : (Emitter.t -> Cil_types.funbehavior -> unit) ->
Cil_types.kernel_function -> unitIter on the behaviors of the given kernel function.
val fold_behaviors : (Emitter.t -> Cil_types.funbehavior -> 'a -> 'a) ->
Cil_types.kernel_function -> 'a -> 'aFold on the behaviors of the given kernel function.
val iter_complete : (Emitter.t -> string list -> unit) -> Cil_types.kernel_function -> unitIter on the complete clauses of the given kernel function.
val fold_complete : (Emitter.t -> string list -> 'a -> 'a) ->
Cil_types.kernel_function -> 'a -> 'aFold on the complete clauses of the given kernel function.
val iter_disjoint : (Emitter.t -> string list -> unit) -> Cil_types.kernel_function -> unitIter on the disjoint clauses of the given kernel function.
val fold_disjoint : (Emitter.t -> string list -> 'a -> 'a) ->
Cil_types.kernel_function -> 'a -> 'aFold on the disjoint clauses of the given kernel function.
val iter_terminates : (Emitter.t -> Cil_types.identified_predicate -> unit) ->
Cil_types.kernel_function -> unitapply f to the terminates predicate if any.
val fold_terminates : (Emitter.t -> Cil_types.identified_predicate -> 'a -> 'a) ->
Cil_types.kernel_function -> 'a -> 'aapply f to the terminates predicate if any.
val iter_decreases : (Emitter.t -> Cil_types.variant -> unit) -> Cil_types.kernel_function -> unitapply f to the decreases term if any.
val fold_decreases : (Emitter.t -> Cil_types.variant -> 'a -> 'a) ->
Cil_types.kernel_function -> 'a -> 'aapply f to the decreases term if any.
val add_code_annot : ?keep_empty:bool ->
Emitter.t ->
?kf:Cil_types.kernel_function ->
Cil_types.stmt -> Cil_types.code_annotation -> unitAdd a new code annotation attached to the given statement. If kf is
provided, the function runs faster.
There might be at most one statement contract associated to a given statement and a given set of enclosing behaviors. Trying to associate more than one will result in a merge of the contracts.
The same things happens with loop assigns and allocates/frees.
The keep_empty argument is only used for loop assigns
and loop allocates, where it is used to decide whether to add the given
code annot in case the corresponding category was empty. It defaults to
true, which is sound wrt ACSL semantics of equating an absence of
annotation with assigns/allocates \everything.
There can be at most one loop variant registered per statement. Attempting to register a second one will result in a fatal error.
val add_assert : Emitter.t ->
?kf:Cil_types.kernel_function ->
Cil_types.stmt -> Cil_types.predicate -> unitAdd an assertion attached to the given statement. If kf is
provided, the function runs faster.
val add_check : Emitter.t ->
?kf:Cil_types.kernel_function ->
Cil_types.stmt -> Cil_types.predicate -> unitAdd a checking assertion attached to the given statement. If kf is
provided, the function runs faster.
val add_admit : Emitter.t ->
?kf:Cil_types.kernel_function ->
Cil_types.stmt -> Cil_types.predicate -> unitAdd an hypothesis assertion attached to the given statement. If kf is
provided, the function runs faster.
val add_global : Emitter.t -> Cil_types.global_annotation -> unitAdd a new global annotation into the program.
type'acontract_component_addition =Emitter.t ->
Cil_types.kernel_function ->
?stmt:Cil_types.stmt -> ?active:string list -> 'a -> unit
type for functions adding a part of a contract (either for global function
or for a given stmt). In the latter case active may be used to state the
list of enclosing behavior(s) for which the contract is supposed to hold.
active defaults to the empty list, meaning that the contract must
always hold.
type'abehavior_component_addition =Emitter.t ->
Cil_types.kernel_function ->
?stmt:Cil_types.stmt -> ?active:string list -> ?behavior:string -> 'a -> unit
type for functions adding a part of a behavior inside a contract. The
contract is found in a similar way as for Annotations.contract_component_addition
functions. Similarly, active has the same meaning as for
Annotations.contract_component_addition.
Default for behavior is Cil.default_behavior_name.
val add_spec : ?register_children:bool ->
Cil_types.spec contract_component_additionAdd new spec into the given contract.
register_children is directly given to the function add_behaviors.
val add_behaviors : ?register_children:bool ->
Cil_types.funbehavior list contract_component_additionAdd new behaviors into the given contract.
if register_children is true (the default), inner clauses of the
behavior will also be registered by the function.
val add_decreases : Emitter.t -> Cil_types.kernel_function -> Cil_types.variant -> unitAdd a decrease clause into the contract of the given function. No decrease clause must previously be attached to this function.
val add_terminates : Cil_types.identified_predicate contract_component_additionAdd a terminates clause into a contract. No terminates clause must previously be attached to this contract.
val add_complete : string list contract_component_additionAdd a new complete behaviors clause into the contract of the given function. Do nothing (but emit a warning) if this clause already exists in the spec.
Fatal if one of the given name
is either an unknown behavior or Cil.default_behavior_name.val add_disjoint : string list contract_component_additionAdd a new disjoint behaviors clause into the contract of the given function. Do nothing (but emit a warning) if this clause already exists in the spec.
Fatal if one of the given name
is either an unknown behavior or Cil.default_behavior_name.val add_requires : Cil_types.identified_predicate list behavior_component_additionAdd new requires clauses into the given behavior.
val add_assumes : Cil_types.identified_predicate list behavior_component_additionAdd new assumes clauses into the given behavior.
Does nothing but emitting a warning if an attempt is made to add assumes clauses to the default behavior.
val add_ensures : (Cil_types.termination_kind * Cil_types.identified_predicate) list
behavior_component_additionAdd new ensures clauses into the given behavior.
val add_assigns : keep_empty:bool -> Cil_types.assigns behavior_component_additionAdd new assigns into the given behavior.
If keep_empty is true and the assigns clause were empty, then
the assigns clause remains empty. (That corresponds to the ACSL semantics of
an assigns clause: if no assigns is specified, that is equivalent to assigns
everything.)
val add_allocates : keep_empty:bool ->
Cil_types.allocation behavior_component_additionAdd new allocates into the given behavior.
See Annotations.add_assigns for the signification of keep_empty
val add_extended : Cil_types.acsl_extension behavior_component_additionval remove_code_annot : Emitter.t ->
?kf:Cil_types.kernel_function ->
Cil_types.stmt -> Cil_types.code_annotation -> unitRemove a code annotation attached to a statement. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok.
val remove_global : Emitter.t -> Cil_types.global_annotation -> unitRemove a global annotation. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok. It is the responsibility of the user to ensure that logic functions/predicates declared in the given annotation are not used elsewhere.
val remove_behavior : ?force:bool ->
Emitter.t -> Cil_types.kernel_function -> Cil_types.funbehavior -> unitRemove a behavior attached to a function. The provided emitter must be the
one that emits this annotation. Do nothing if the annotation does not exist,
or if the emitter is not ok. If force is false (which is the default),
it is not possible to remove a behavior whose the name is used in a
complete/disjoint clause. If force is true, it is the responsibility
of the user to ensure that complete/disjoint clauses refer to existing
behaviors.
val remove_behavior_components : Emitter.t -> Cil_types.kernel_function -> Cil_types.funbehavior -> unitremove all the component of a behavior, but keeps the name (so as to avoid issues with disjoint/complete clauses).
val remove_decreases : Emitter.t -> Cil_types.kernel_function -> unitRemove the decreases clause attached to a function. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok.
val remove_terminates : Emitter.t -> Cil_types.kernel_function -> unitRemove the terminates clause attached to a function. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok.
val remove_complete : Emitter.t -> Cil_types.kernel_function -> string list -> unitRemove a complete behaviors clause attached to a function. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok.
val remove_disjoint : Emitter.t -> Cil_types.kernel_function -> string list -> unitRemove a disjoint behaviors clause attached to a function. The provided emitter must be the one that emits this annotation. Do nothing if the annotation does not exist, or if the emitter is not ok.
val remove_requires : Emitter.t ->
Cil_types.kernel_function -> Cil_types.identified_predicate -> unitRemove a requires clause from the spec of the given function. Do nothing if the predicate does not exist or was not emitted by the given emitter.
val remove_assumes : Emitter.t ->
Cil_types.kernel_function -> Cil_types.identified_predicate -> unitRemove an assumes clause from the spec of the given function. Do nothing if the predicate does not exist or was not emitted by the given emitter.
val remove_ensures : Emitter.t ->
Cil_types.kernel_function ->
Cil_types.termination_kind * Cil_types.identified_predicate -> unitRemove a post-condition from the spec of the given function. Do nothing if the post-cond does not exist or was not emitted by the given emitter.
val remove_allocates : Emitter.t -> Cil_types.kernel_function -> Cil_types.allocation -> unitRemove the corresponding allocation clause. Do nothing if the clause does not exist or was not emitted by the given emitter.
val remove_assigns : Emitter.t -> Cil_types.kernel_function -> Cil_types.assigns -> unitRemove the corresponding assigns clause. Do nothing if the clause does not exist or was not emitted by the given emitter.
val remove_extended : Emitter.t -> Cil_types.kernel_function -> Cil_types.acsl_extension -> unitval has_code_annot : ?emitter:Emitter.t -> Cil_types.stmt -> booltrue iff there is some annotation attached to the given statement
(and generated by the given emitter, if any).val emitter_of_code_annot : Cil_types.code_annotation -> Cil_types.stmt -> Emitter.tNot_found if the code annotation does not exist, or if it is
registered at another statement.val emitter_of_global : Cil_types.global_annotation -> Emitter.tNot_found if the global annotation is not registered.val logic_info_of_global : string -> Cil_types.logic_info listNot_found if no global annotation declare such a variableval behavior_names_of_stmt_in_kf : Cil_types.kernel_function -> string listval code_annot_of_kf : Cil_types.kernel_function ->
(Cil_types.stmt * Cil_types.code_annotation) listval fresh_behavior_name : Cil_types.kernel_function -> string -> stringval code_annot_state : State.tThe state which stores all the code annotations of the program.
val funspec_state : State.tThe state which stores all the function contracts of the program.
val global_state : State.tThe state which stores all the global annotations of the program.