From ab3a58317a42b84caab2bc46d57c0a52b17c0ca2 Mon Sep 17 00:00:00 2001
From: Valentin Perrelle <valentin.perrelle@cea.fr>
Date: Sat, 18 Sep 2021 17:35:48 +0200
Subject: [PATCH] [Eva] api: Automatically generates Eva.mli

---
 Makefile                                      |  20 ++
 src/plugins/value/Eva.mli                     | 201 ++++++++++++++----
 src/plugins/value/domains/cvalue/builtins.mli |   2 +
 src/plugins/value/eva-api.sh                  |  27 +++
 src/plugins/value/eval.mli                    |   3 +-
 src/plugins/value/legacy/eval_terms.mli       |  18 +-
 src/plugins/value/utils/eva_annotations.mli   |  23 +-
 src/plugins/value/utils/results.mli           |   3 +
 src/plugins/value/utils/unit_tests.mli        |   4 +-
 src/plugins/value/utils/value_results.mli     |   6 +-
 src/plugins/value/value_parameters.mli        |  13 +-
 11 files changed, 263 insertions(+), 57 deletions(-)
 create mode 100755 src/plugins/value/eva-api.sh

diff --git a/Makefile b/Makefile
index 478ee8f3ab6..f580c4984d3 100644
--- a/Makefile
+++ b/Makefile
@@ -825,6 +825,8 @@ PLUGIN_EXTRA_DIRS:=engine values domains api domains/cvalue domains/apron \
 	domains/gauges domains/equality legacy partitioning utils gui_files \
 	api values/numerors domains/numerors
 PLUGIN_TESTS_DIRS+=value/traces
+PLUGIN_GENERATED:=$(PLUGIN_DIR)/Eva.mli
+PLUGIN_DISTRIB_EXTERNAL+=$(PLUGIN_DIR)/eva-api.sh
 
 # Files for the binding to Apron domains. Only available if Apron is available.
 ifeq ($(HAS_APRON),yes)
@@ -927,8 +929,26 @@ VALUE_TYPES:=$(addprefix src/plugins/value_types/,\
 PLUGIN_TYPES_CMO:=$(VALUE_TYPES)
 PLUGIN_TYPES_TODOC:=$(addsuffix .mli,$(VALUE_TYPES))
 
+# Eva API
+API_HEADER := headers/open-source/CEA_LGPL_OR_PROPRIETARY
+API_MLI := $(addprefix $(PLUGIN_DIR)/, \
+  utils/results.mli utils/value_results.mli value_parameters.mli \
+  legacy/eval_terms.mli utils/unit_tests.mli utils/eva_annotations.mli \
+  eval.mli domains/cvalue/builtins.mli)
+
+$(PLUGIN_DIR)/Eva.mli: $(PLUGIN_DIR)/eva-api.sh Makefile $(API_HEADER) $(API_MLI)
+	$(PRINT_MAKING) $@
+	$(RM) $@ $@.tmp
+	$< $(API_HEADER) $(API_MLI) > $@.tmp
+	$(CHMOD_RO) $@.tmp
+	$(MV) $@.tmp $@
+
+clean::
+	$(RM) $(PLUGIN_DIR)/Eva.mli
+
 $(eval $(call include_generic_plugin_Makefile,$(PLUGIN_NAME)))
 
+
 #########
 # Reduc #
 #########
diff --git a/src/plugins/value/Eva.mli b/src/plugins/value/Eva.mli
index 74ac173305e..71b28373ba5 100644
--- a/src/plugins/value/Eva.mli
+++ b/src/plugins/value/Eva.mli
@@ -3,7 +3,7 @@
 (*  This file is part of Frama-C.                                         *)
 (*                                                                        *)
 (*  Copyright (C) 2007-2021                                               *)
-(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies           *)
 (*         alternatives)                                                  *)
 (*                                                                        *)
 (*  you can redistribute it and/or modify it under the terms of the GNU   *)
@@ -20,90 +20,177 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** Analysis for values and pointers *)
+(* This file is generated. Do not edit. *)
+
+module Results: sig
+  (* Usage sketch :
+  
+     Eva.Results.(before stmt |> in_callstack cs |> eval_var vi |> as_int)
+  
+     or, if you prefer
+  
+     Eva.Results.(as_int (eval_var vi (in_callstack cs (before stmt))))
+  *)
+  
+  type callstack = (Cil_types.kernel_function * Cil_types.kinstr) list
+  
+  type request
+  type evaluation
+  type lvaluation
+  
+  type error = Bottom | Top | DisabledDomain
+  type 'a result = ('a,error) Result.t
+  
+  (* Control point selection *)
+  val at_start : request
+  val at_end : request
+  val at_start_of : Cil_types.kernel_function -> request
+  val at_end_of : Cil_types.kernel_function -> request
+  val before : Cil_types.stmt -> request
+  val after : Cil_types.stmt -> request
+  val before_kinstr : Cil_types.kinstr -> request
+  val after_kinstr : Cil_types.kinstr -> request
+  
+  (* Callstack selection *)
+  val in_callstack : callstack -> request -> request
+  val in_callstacks : callstack list -> request -> request
+  val filter_callstack : (callstack -> bool) -> request -> request
+  
+  (* Working with callstacks *)
+  val callstacks : request -> callstack list
+  val fold_callstacks : (callstack -> request -> 'a -> 'a) -> 'a -> request -> 'a
+  val by_callstack : request -> (callstack * request) list
+  
+  (* State requests *)
+  val equality_class : Cil_types.exp -> request -> Cil_types.exp list result
+  val as_cvalue_model : request -> Cvalue.Model.t result
+  
+  (* Evaluation *)
+  val eval_var : Cil_types.varinfo -> request -> evaluation
+  val eval_lval : Cil_types.lval -> request -> evaluation
+  val eval_exp : Cil_types.exp -> request -> evaluation
+  
+  val eval_address : Cil_types.lval -> request -> lvaluation
+  
+  (* Value conversion *)
+  val as_int : evaluation -> int result
+  val as_integer : evaluation -> Integer.t result
+  val as_float : evaluation -> float result
+  val as_functions : evaluation -> Cil_types.kernel_function list result (* Ignores non-function values *)
+  val as_ival : evaluation -> Ival.t result
+  val as_fval : evaluation -> Fval.t result
+  val as_cvalue : evaluation -> Cvalue.V.t result
+  
+  val as_location : lvaluation -> Locations.location result
+  val as_zone : lvaluation -> Locations.Zone.t result
+  
+  (* Evaluation properties *)
+  val is_initialized : evaluation -> bool
+  val alarms : evaluation -> Alarms.t list
+  
+  (* Bottomness *)
+  val is_bottom : evaluation -> bool
+  val is_called : Cil_types.kernel_function -> bool (* called during the analysis, not by the actual program *)
+  val is_reachable : Cil_types.stmt -> bool (* reachable by the analysis, not by the actual program *)
+  
+end
 
 module Value_results: sig
   type results
-
+  
   val get_results: unit -> results
   val set_results: results -> unit
   val merge: results -> results -> results
   val change_callstacks:
     (Value_types.callstack -> Value_types.callstack) -> results -> results
+  (** Change the callstacks for the results for which this is meaningful.
+      For technical reasons, the top of the callstack must currently
+      be preserved. *)
 end
 
 module Value_parameters: sig
   (** Returns the list (name, descr) of currently enabled abstract domains. *)
   val enabled_domains: unit -> (string * string) list
-
+  
   (** [use_builtin kf name] instructs the analysis to use the builtin [name]
       to interpret calls to function [kf].
       Raises [Not_found] if there is no builtin of name [name]. *)
   val use_builtin: Cil_types.kernel_function -> string -> unit
-
+  
   (** [use_global_value_partitioning vi] instructs the analysis to use
       value partitioning on the global variable [vi]. *)
   val use_global_value_partitioning: Cil_types.varinfo -> unit
 end
 
 module Eval_terms: sig
-  (** Evaluation environment, built by [env_annot]. *)
+  type labels_states = Cvalue.Model.t Cil_datatype.Logic_label.Map.t
+  
+  (** Evaluation environment. Currently available are function Pre and Post, or
+      the environment to evaluate an annotation *)
   type eval_env
-
-  (** Dependencies needed to evaluate a term or a predicate. *)
-  type logic_deps = Locations.Zone.t Cil_datatype.Logic_label.Map.t
-
-  type labels_states = Db.Value.state Cil_datatype.Logic_label.Map.t
-
   val env_annot :
-    ?c_labels:labels_states -> pre:Db.Value.state -> here:Db.Value.state ->
+    ?c_labels:labels_states -> pre:Cvalue.Model.t -> here:Cvalue.Model.t ->
     unit -> eval_env
-
+  (** Dependencies needed to evaluate a term or a predicate *)
+  type logic_deps = Locations.Zone.t Cil_datatype.Logic_label.Map.t
   (** [predicate_deps env p] computes the logic dependencies needed to evaluate
       [p] in the given evaluation environment [env].
       @return None on either an evaluation error or on unsupported construct. *)
   val predicate_deps: eval_env -> Cil_types.predicate -> logic_deps option
 end
 
-
 module Unit_tests: sig
-  (** Runs the unit tests of Eva. *)
+  (** Currently tested by this module:
+      - semantics of sign values. *)
+  
+  (** Runs some programmatic tests on Eva. *)
   val run: unit -> unit
 end
 
-(** Register special annotations to locally guide the partitioning of states
-    performed by an Eva analysis. *)
 module Eva_annotations: sig
-
+  (** Register special annotations to locally guide the partitioning of states
+      performed by an Eva analysis:
+  
+      - slevel annotations: "slevel default", "slevel merge" and "slevel i"
+      - loop unroll annotations: "loop unroll term"
+      - value partitioning annotations: "split term" and "merge term"
+      - subdivision annotations: "subdivide i"
+  
+      Widen hints annotations are still registered in !{widen_hints_ext.ml}. *)
+  
   (** Annotations tweaking the behavior of the -eva-slevel paramter. *)
   type slevel_annotation =
     | SlevelMerge        (** Join all states separated by slevel. *)
     | SlevelDefault      (** Use the limit defined by -eva-slevel. *)
     | SlevelLocal of int (** Use the given limit instead of -eva-slevel. *)
     | SlevelFull         (** Remove the limit of number of separated states. *)
-
+  
   (** Loop unroll annotations. *)
   type unroll_annotation =
     | UnrollAmount of Cil_types.term (** Unroll the n first iterations. *)
     | UnrollFull (** Unroll amount defined by -eva-default-loop-unroll. *)
-
+  
   type split_kind = Static | Dynamic
+  
   type split_term =
     | Expression of Cil_types.exp
     | Predicate of Cil_types.predicate
-
+  
   (** Split/merge annotations for value partitioning.  *)
   type flow_annotation =
     | FlowSplit of split_term * split_kind
     (** Split states according to a term. *)
     | FlowMerge of split_term
     (** Merge states separated by a previous split. *)
-
+  
+  type allocation_kind = By_stack | Fresh | Fresh_weak | Imprecise
+  
   val get_slevel_annot : Cil_types.stmt -> slevel_annotation option
   val get_unroll_annot : Cil_types.stmt -> unroll_annotation list
   val get_flow_annot : Cil_types.stmt -> flow_annotation list
   val get_subdivision_annot : Cil_types.stmt -> int list
-
+  val get_allocation: Cil_types.stmt -> allocation_kind
+  
   val add_slevel_annot : emitter:Emitter.t ->
     Cil_types.stmt -> slevel_annotation -> unit
   val add_unroll_annot : emitter:Emitter.t ->
@@ -114,33 +201,75 @@ module Eva_annotations: sig
     Cil_types.stmt -> int -> unit
 end
 
-(** Analysis builtins for the cvalue domain, more efficient than the analysis
-    of the C functions. See {builtins.mli} for more details. *)
+module Eval: sig
+  (** Can the results of a function call be cached with memexec? *)
+  type cacheable =
+    | Cacheable      (** Functions whose result can be safely cached *)
+    | NoCache        (** Functions whose result should not be cached, but for
+                         which the caller can still be cached. Typically,
+                         functions printing something during the analysis. *)
+    | NoCacheCallers (** Functions for which neither the call, neither the
+                         callers, can be cached *)
+end
+
 module Builtins: sig
+  (** Eva analysis builtins for the cvalue domain, more efficient than their
+      equivalent in C. *)
+  
   open Cil_types
-
+  
   exception Invalid_nb_of_args of int
   exception Outside_builtin_possibilities
-
+  
+  (* Signature of a builtin: type of the result, and type of the arguments. *)
   type builtin_type = unit -> typ * typ list
-  type cacheable = Cacheable | NoCache | NoCacheCallers
-
+  
+  (** Can the results of a builtin be cached? See {eval.mli} for more details.*)
+  type cacheable = Eval.cacheable = Cacheable | NoCache | NoCacheCallers
+  
   type full_result = {
     c_values: (Cvalue.V.t option * Cvalue.Model.t) list;
+    (** A list of results, consisting of:
+        - the value returned (ie. what is after the 'return' C keyword)
+        - the memory state after the function has been executed. *)
     c_clobbered: Base.SetLattice.t;
+    (** An over-approximation of the bases in which addresses of local variables
+        might have been written *)
     c_from: (Function_Froms.froms * Locations.Zone.t) option;
+    (** If not None, the froms of the function, and its sure outputs;
+        i.e. the dependencies of the result and of each zone written to. *)
   }
-
+  
+  (** The result of a builtin can be given in different forms. *)
   type call_result =
     | States of Cvalue.Model.t list
+    (** A disjunctive list of post-states at the end of the C function.
+        Can only be used if the C function does not write the address of local
+        variables, does not read other locations than the call arguments, and
+        does not write other locations than the result. *)
     | Result of Cvalue.V.t list
+    (** A disjunctive list of resulting values. The specification is used to
+        compute the post-state, in which the result is replaced by the values
+        computed by the builtin. *)
     | Full of full_result
-
+    (** See [full_result] type. *)
+  
+  (** Type of a cvalue builtin, whose arguments are:
+      - the memory state at the beginning of the function call;
+      - the list of arguments of the function call. *)
   type builtin = Cvalue.Model.t -> (exp * Cvalue.V.t) list -> call_result
-
+  
+  (** [register_builtin name ?replace ?typ cacheable f] registers the function [f]
+      as a builtin to be used instead of the C function of name [name].
+      If [replace] is provided, the builtin is also used instead of the C function
+      of name [replace], unless option -eva-builtin-auto is disabled.
+      If [typ] is provided, consistency between the expected [typ] and the type of
+      the C function is checked before using the builtin.
+      The results of the builtin are cached according to [cacheable]. *)
   val register_builtin:
-    string -> ?replace:string -> ?typ:builtin_type -> cacheable ->
-    builtin -> unit
-
+    string -> ?replace:string -> ?typ:builtin_type -> cacheable -> builtin -> unit
+  
+  (** Has a builtin been registered with the given name? *)
   val is_builtin: string -> bool
 end
+
diff --git a/src/plugins/value/domains/cvalue/builtins.mli b/src/plugins/value/domains/cvalue/builtins.mli
index 353be4b52e8..ac9751b56a8 100644
--- a/src/plugins/value/domains/cvalue/builtins.mli
+++ b/src/plugins/value/domains/cvalue/builtins.mli
@@ -20,6 +20,7 @@
 (*                                                                        *)
 (**************************************************************************)
 
+[@@@ api_start]
 (** Eva analysis builtins for the cvalue domain, more efficient than their
     equivalent in C. *)
 
@@ -78,6 +79,7 @@ val register_builtin:
 
 (** Has a builtin been registered with the given name? *)
 val is_builtin: string -> bool
+[@@@ api_end]
 
 (** Prepares the builtins to be used for an analysis. Must be called at the
     beginning of each Eva analysis. Warns about builtins of incompatible types,
diff --git a/src/plugins/value/eva-api.sh b/src/plugins/value/eva-api.sh
new file mode 100755
index 00000000000..9da4452f3ff
--- /dev/null
+++ b/src/plugins/value/eva-api.sh
@@ -0,0 +1,27 @@
+#!/bin/bash -eu
+
+header=$1
+shift
+
+IFS='' # for read to keep spaces
+
+printf '('
+printf '%0.1s' '*'{1..74}
+printf ')\n'
+while read -r line
+do
+    printf '(*  %-68s  *)\n' $line
+done < $header
+printf '('
+printf '%0.1s' '*'{1..74}
+printf ')\n\n'
+printf '(* This file is generated. Do not edit. *)\n\n'
+
+for i in "$@"
+do
+    file=$(basename $i)
+    module=${file%.*}
+    printf 'module %s: sig\n' ${module^}
+    awk '/\[@@@ api_start\]/{flag=1;next} /\[@@@ api_end\]/{flag=0} flag{ print  " ", $0 }' $i
+    printf 'end\n\n'
+done
diff --git a/src/plugins/value/eval.mli b/src/plugins/value/eval.mli
index 5714172358f..4c7bcc873aa 100644
--- a/src/plugins/value/eval.mli
+++ b/src/plugins/value/eval.mli
@@ -270,6 +270,7 @@ type recursion = {
   (** Same withdrawal as the previous field, for bases. *)
 }
 
+[@@@ api_start]
 (** Can the results of a function call be cached with memexec? *)
 type cacheable =
   | Cacheable      (** Functions whose result can be safely cached *)
@@ -278,7 +279,7 @@ type cacheable =
                        functions printing something during the analysis. *)
   | NoCacheCallers (** Functions for which neither the call, neither the
                        callers, can be cached *)
-
+[@@@ api_end]
 (*
 Local Variables:
 compile-command: "make -C ../../.."
diff --git a/src/plugins/value/legacy/eval_terms.mli b/src/plugins/value/legacy/eval_terms.mli
index e63e6a53180..59a798c9e55 100644
--- a/src/plugins/value/legacy/eval_terms.mli
+++ b/src/plugins/value/legacy/eval_terms.mli
@@ -49,17 +49,22 @@ val pretty_logic_evaluation_error :
 
 exception LogicEvalError of logic_evaluation_error
 
+[@@@ api_start]
 type labels_states = Cvalue.Model.t Cil_datatype.Logic_label.Map.t
 
 (** Evaluation environment. Currently available are function Pre and Post, or
     the environment to evaluate an annotation *)
 type eval_env
+[@@@ api_end]
 
 val make_env: Model.t Abstract_domain.logic_environment -> Model.t -> eval_env
 
 val env_pre_f : pre:Model.t -> unit -> eval_env
+[@@@ api_start]
 val env_annot :
-  ?c_labels:labels_states -> pre:Model.t -> here:Model.t -> unit -> eval_env
+  ?c_labels:labels_states -> pre:Cvalue.Model.t -> here:Cvalue.Model.t ->
+  unit -> eval_env
+[@@@ api_end]
 val env_post_f :
   ?c_labels:labels_states -> pre:Model.t -> post:Model.t ->
   result:varinfo option -> unit -> eval_env
@@ -70,8 +75,10 @@ val env_only_here: Model.t -> eval_env
 
 val env_current_state: eval_env -> Model.t
 
+[@@@ api_start]
 (** Dependencies needed to evaluate a term or a predicate *)
-type logic_deps = Zone.t Cil_datatype.Logic_label.Map.t
+type logic_deps = Locations.Zone.t Cil_datatype.Logic_label.Map.t
+[@@@ api_end]
 
 (** Three modes to handle the alarms when evaluating a logical term. *)
 type alarm_mode =
@@ -110,7 +117,12 @@ val eval_tlval_as_zone :
 val eval_predicate :
   eval_env -> predicate -> predicate_status
 
-val predicate_deps: eval_env -> predicate -> logic_deps option
+[@@@ api_start]
+(** [predicate_deps env p] computes the logic dependencies needed to evaluate
+    [p] in the given evaluation environment [env].
+    @return None on either an evaluation error or on unsupported construct. *)
+val predicate_deps: eval_env -> Cil_types.predicate -> logic_deps option
+[@@@ api_end]
 
 val reduce_by_predicate :
   eval_env -> bool -> predicate -> eval_env
diff --git a/src/plugins/value/utils/eva_annotations.mli b/src/plugins/value/utils/eva_annotations.mli
index df768e5a1fb..69cd10db0d0 100644
--- a/src/plugins/value/utils/eva_annotations.mli
+++ b/src/plugins/value/utils/eva_annotations.mli
@@ -20,7 +20,10 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** Registers Eva annotations:
+[@@@ api_start]
+(** Register special annotations to locally guide the partitioning of states
+    performed by an Eva analysis:
+
     - slevel annotations: "slevel default", "slevel merge" and "slevel i"
     - loop unroll annotations: "loop unroll term"
     - value partitioning annotations: "split term" and "merge term"
@@ -28,15 +31,17 @@
 
     Widen hints annotations are still registered in !{widen_hints_ext.ml}. *)
 
+(** Annotations tweaking the behavior of the -eva-slevel paramter. *)
 type slevel_annotation =
-  | SlevelMerge
-  | SlevelDefault
-  | SlevelLocal of int
-  | SlevelFull
+  | SlevelMerge        (** Join all states separated by slevel. *)
+  | SlevelDefault      (** Use the limit defined by -eva-slevel. *)
+  | SlevelLocal of int (** Use the given limit instead of -eva-slevel. *)
+  | SlevelFull         (** Remove the limit of number of separated states. *)
 
+(** Loop unroll annotations. *)
 type unroll_annotation =
-  | UnrollAmount of Cil_types.term
-  | UnrollFull
+  | UnrollAmount of Cil_types.term (** Unroll the n first iterations. *)
+  | UnrollFull (** Unroll amount defined by -eva-default-loop-unroll. *)
 
 type split_kind = Static | Dynamic
 
@@ -44,9 +49,12 @@ type split_term =
   | Expression of Cil_types.exp
   | Predicate of Cil_types.predicate
 
+(** Split/merge annotations for value partitioning.  *)
 type flow_annotation =
   | FlowSplit of split_term * split_kind
+  (** Split states according to a term. *)
   | FlowMerge of split_term
+  (** Merge states separated by a previous split. *)
 
 type allocation_kind = By_stack | Fresh | Fresh_weak | Imprecise
 
@@ -64,3 +72,4 @@ val add_flow_annot : emitter:Emitter.t ->
   Cil_types.stmt -> flow_annotation -> unit
 val add_subdivision_annot : emitter:Emitter.t ->
   Cil_types.stmt -> int -> unit
+[@@@ api_end]
diff --git a/src/plugins/value/utils/results.mli b/src/plugins/value/utils/results.mli
index 0e0a0c69391..870feaea2b9 100644
--- a/src/plugins/value/utils/results.mli
+++ b/src/plugins/value/utils/results.mli
@@ -20,6 +20,7 @@
 (*                                                                        *)
 (**************************************************************************)
 
+[@@@ api_start]
 (* Usage sketch :
 
    Eva.Results.(before stmt |> in_callstack cs |> eval_var vi |> as_int)
@@ -89,3 +90,5 @@ val alarms : evaluation -> Alarms.t list
 val is_bottom : evaluation -> bool
 val is_called : Cil_types.kernel_function -> bool (* called during the analysis, not by the actual program *)
 val is_reachable : Cil_types.stmt -> bool (* reachable by the analysis, not by the actual program *)
+
+[@@@ api_end]
diff --git a/src/plugins/value/utils/unit_tests.mli b/src/plugins/value/utils/unit_tests.mli
index cf1fae9cef8..db0856b3653 100644
--- a/src/plugins/value/utils/unit_tests.mli
+++ b/src/plugins/value/utils/unit_tests.mli
@@ -20,8 +20,10 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** Currently tested by this file:
+[@@@ api_start]
+(** Currently tested by this module:
     - semantics of sign values. *)
 
 (** Runs some programmatic tests on Eva. *)
 val run: unit -> unit
+[@@@ api_end]
diff --git a/src/plugins/value/utils/value_results.mli b/src/plugins/value/utils/value_results.mli
index 9592d1e753f..1302d5437c8 100644
--- a/src/plugins/value/utils/value_results.mli
+++ b/src/plugins/value/utils/value_results.mli
@@ -20,10 +20,6 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** This file will ultimately contain all the results computed by Value
-    (which must be moved out of Db.Value), both per stack and globally. *)
-
-
 open Cil_types
 
 val is_called: kernel_function -> bool
@@ -36,6 +32,7 @@ val is_non_terminating_instr: stmt -> bool
     statements that are instructions. *)
 
 (** {2 Results} *)
+[@@@ api_start]
 type results
 
 val get_results: unit -> results
@@ -46,6 +43,7 @@ val change_callstacks:
 (** Change the callstacks for the results for which this is meaningful.
     For technical reasons, the top of the callstack must currently
     be preserved. *)
+[@@@ api_end]
 
 (*
 Local Variables:
diff --git a/src/plugins/value/value_parameters.mli b/src/plugins/value/value_parameters.mli
index a05cde2a46d..41cd18d4647 100644
--- a/src/plugins/value/value_parameters.mli
+++ b/src/plugins/value/value_parameters.mli
@@ -230,16 +230,19 @@ val register_builtin: string -> unit
 (** Registers available domain names for the -eva-domains option. *)
 val register_domain: name:string -> descr:string -> unit
 
-(** Returns the list (name, descr) of currently enabled domains. *)
+[@@@ api_start]
+(** Returns the list (name, descr) of currently enabled abstract domains. *)
 val enabled_domains: unit -> (string * string) list
 
-(** [use_builtin kf b] adds a builtin override for function `kf` to
-    builtin `b`. *)
+(** [use_builtin kf name] instructs the analysis to use the builtin [name]
+    to interpret calls to function [kf].
+    Raises [Not_found] if there is no builtin of name [name]. *)
 val use_builtin: Cil_types.kernel_function -> string -> unit
 
-(** [use_global_value_partitioning vi] enable value partitioning on the global
-    variable `vi`. *)
+(** [use_global_value_partitioning vi] instructs the analysis to use
+    value partitioning on the global variable [vi]. *)
 val use_global_value_partitioning: Cil_types.varinfo -> unit
+[@@@ api_end]
 
 (*
 Local Variables:
-- 
GitLab