From d18736f143b45c9454775c1ad857aa8e4f71d793 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Wed, 2 Aug 2023 15:08:16 +0200
Subject: [PATCH] [Eva] Removes file eva_types.ml from kernel.

---
 .../abstract_interp/eva_types.ml              | 188 ------------------
 .../abstract_interp/eva_types.mli             |  63 ------
 src/plugins/eva/Eva.mli                       |   6 +-
 src/plugins/eva/dune                          |   5 +-
 src/plugins/eva/types/callstack.ml            | 164 ++++++++++++++-
 src/plugins/eva/types/callstack.mli           |   6 +-
 6 files changed, 171 insertions(+), 261 deletions(-)
 delete mode 100644 src/kernel_services/abstract_interp/eva_types.ml
 delete mode 100644 src/kernel_services/abstract_interp/eva_types.mli

diff --git a/src/kernel_services/abstract_interp/eva_types.ml b/src/kernel_services/abstract_interp/eva_types.ml
deleted file mode 100644
index 229782bc556..00000000000
--- a/src/kernel_services/abstract_interp/eva_types.ml
+++ /dev/null
@@ -1,188 +0,0 @@
-(**************************************************************************)
-(*                                                                        *)
-(*  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).            *)
-(*                                                                        *)
-(**************************************************************************)
-
-let stable_hash x = Hashtbl.seeded_hash 0 x
-
-let dkey_callstack = Kernel.register_category "callstack"
-
-module Callstack =
-struct
-  module Thread = Int (* Threads are identified by integers *)
-  module Kf = Kernel_function
-  module Stmt = Cil_datatype.Stmt
-  module Var = Cil_datatype.Varinfo
-
-  module Call = Datatype.Pair_with_collections(Kf)(Stmt)
-      (struct let module_name = "Eva.Callstack.Call" end)
-
-  module Calls = Datatype.List (Call)
-
-  type callstack = {
-    thread: int;
-    entry_point: Kernel_function.t;
-    stack: Call.t list;
-  }
-
-  module Prototype =
-  struct
-    include Datatype.Serializable_undefined
-
-    type t = callstack = {
-      thread: int;
-      entry_point: Kernel_function.t;
-      stack: Call.t list;
-    }
-    [@@deriving eq, ord]
-
-    let name = "Eva.Callstack"
-
-    let reprs =
-      List.concat_map (fun stack ->
-          List.map (fun entry_point -> { thread = 0; entry_point; stack })
-            Kernel_function.reprs)
-        Calls.reprs
-
-    let pretty fmt cs =
-      let pp_call fmt (kf,stmt) =
-        Format.fprintf fmt "%a :: %a <-@ "
-          Kf.pretty kf
-          Cil_datatype.Location.pretty (Stmt.loc stmt)
-      in
-      Format.fprintf fmt "@[<hv>";
-      List.iter (pp_call fmt) cs.stack;
-      Format.fprintf fmt "%a@]" Kernel_function.pretty cs.entry_point
-
-    let hash cs =
-      Hashtbl.hash
-        (cs.thread, Kernel_function.hash cs.entry_point, Calls.hash cs.stack)
-  end
-
-  type call = Call.t
-
-  include Datatype.Make_with_collections (Prototype)
-
-  let pretty_debug = pretty
-
-  let compare_lex cs1 cs2 =
-    if cs1 == cs2 then 0 else
-      let c = Thread.compare cs1.thread cs2.thread in
-      if c <> 0 then c else
-        let c = Kernel_function.compare cs1.entry_point cs2.entry_point in
-        if c <> 0 then c else
-          Calls.compare (List.rev cs1.stack) (List.rev cs2.stack)
-
-  (* Stack manipulation *)
-
-  let init ?(thread=0) kf = { thread; entry_point=kf; stack = [] }
-
-  let push kf stmt cs =
-    { cs with stack = (kf, stmt) :: cs.stack }
-
-  let pop cs =
-    match cs.stack with
-    | [] -> None
-    | _ :: tail -> Some { cs with stack = tail }
-
-  let top cs =
-    match cs.stack with
-    | [] -> None
-    | (kf, stmt) :: _ -> Some (kf, stmt)
-
-  let top_kf cs =
-    match cs.stack with
-    | (kf, _stmt) :: _ -> kf
-    | [] -> cs.entry_point
-
-  let top_callsite cs =
-    match cs.stack with
-    | [] -> Cil_types.Kglobal
-    | (_kf, stmt) :: _ -> Cil_types.Kstmt stmt
-
-  let top_call cs =
-    match cs.stack with
-    | (kf, stmt) :: _ -> kf, Cil_types.Kstmt stmt
-    | [] -> cs.entry_point, Cil_types.Kglobal
-
-  let top_caller cs =
-    match cs.stack with
-    | _ :: (kf, _) :: _ -> Some kf
-    | [_] -> Some cs.entry_point
-    | [] -> None
-
-  (* Conversion *)
-
-  let to_kf_list cs = cs.entry_point :: List.rev_map fst cs.stack
-  let to_stmt_list cs = List.rev_map snd cs.stack
-
-  let to_call_list cs =
-    let l =
-      List.rev_map (fun (kf, stmt) -> (kf, Cil_types.Kstmt stmt)) cs.stack
-    in
-    (cs.entry_point, Cil_types.Kglobal) :: l
-
-  (* Stable hash and pretty-printing *)
-
-  let stmt_hash s =
-    let pos = fst (Cil_datatype.Stmt.loc s) in
-    stable_hash (pos.Filepath.pos_path, pos.Filepath.pos_lnum)
-
-  let kf_hash kf = stable_hash (Kernel_function.get_name kf)
-
-  let rec calls_hash = function
-    | [] -> 0
-    | (kf, stmt) :: tl -> stable_hash (kf_hash kf, stmt_hash stmt, calls_hash tl)
-
-  let stable_hash { thread; entry_point; stack } =
-    let p = stable_hash (thread, kf_hash entry_point, calls_hash stack) in
-    p mod 11_316_496 (* 58 ** 4 *)
-
-  let base58_map = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
-
-  (* Converts [i] into a fixed-length, 4-wide string in base-58 *)
-  let base58_of_int n =
-    let buf = Bytes.create 4 in
-    Bytes.set buf 0 (String.get base58_map (n mod 58));
-    let n = n / 58 in
-    Bytes.set buf 1 (String.get base58_map (n mod 58));
-    let n = n / 58 in
-    Bytes.set buf 2 (String.get base58_map (n mod 58));
-    let n = n / 58 in
-    Bytes.set buf 3 (String.get base58_map (n mod 58));
-    Bytes.to_string buf
-
-  let pretty_hash fmt callstack =
-    if Kernel.is_debug_key_enabled dkey_callstack then
-      Format.fprintf fmt "<%s> " (base58_of_int (stable_hash callstack))
-    else Format.ifprintf fmt ""
-
-  let pretty_short fmt callstack =
-    Format.fprintf fmt "%a" pretty_hash callstack;
-    let list = List.rev (to_kf_list callstack) in
-    Pretty_utils.pp_flowlist ~left:"" ~sep:" <- " ~right:""
-      (fun fmt kf -> Kernel_function.pretty fmt kf)
-      fmt list
-
-  let pretty fmt callstack =
-    Format.fprintf fmt "@[<hv>%a" pretty_hash callstack;
-    pretty fmt callstack;
-    Format.fprintf fmt "@]"
-end
diff --git a/src/kernel_services/abstract_interp/eva_types.mli b/src/kernel_services/abstract_interp/eva_types.mli
deleted file mode 100644
index d5406e1d648..00000000000
--- a/src/kernel_services/abstract_interp/eva_types.mli
+++ /dev/null
@@ -1,63 +0,0 @@
-(**************************************************************************)
-(*                                                                        *)
-(*  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).            *)
-(*                                                                        *)
-(**************************************************************************)
-
-(** This module is here for compatibility reasons only and will be removed in
-    future versions. Use [Eva.Callstack] instead *)
-
-module Callstack :
-sig
-  type call = Cil_types.kernel_function * Cil_types.stmt
-
-  module Call : Datatype.S with type t = call
-
-  type callstack = {
-    thread: int;
-    entry_point: Cil_types.kernel_function;
-    stack: call list;
-  }
-
-  include Datatype.S_with_collections with type t = callstack
-
-  val pretty_hash : Format.formatter -> t -> unit
-  val pretty_short : Format.formatter -> t -> unit
-  val pretty_debug : Format.formatter -> t -> unit
-
-  val compare_lex : t -> t -> int
-
-  val init : ?thread:int -> Cil_types.kernel_function -> t
-
-  val push : Cil_types.kernel_function -> Cil_types.stmt -> t -> t
-  val pop : t -> t option
-  val top : t -> (Cil_types.kernel_function * Cil_types.stmt) option
-  val top_kf : t -> Cil_types.kernel_function
-  val top_callsite : t -> Cil_types.kinstr
-  val top_call : t -> Cil_types.kernel_function * Cil_types.kinstr
-  val top_caller : t -> Cil_types.kernel_function option
-
-  val to_kf_list : t -> Cil_types.kernel_function list
-  val to_stmt_list : t -> Cil_types.stmt list
-  val to_call_list : t -> (Cil_types.kernel_function * Cil_types.kinstr) list
-end
-[@@alert db_deprecated
-    "Eva_types is only provided for compatibility reason and will be removed \
-     in a future version of Frama-C. Please use the Eva.Callstack in the \
-     public API instead."]
diff --git a/src/plugins/eva/Eva.mli b/src/plugins/eva/Eva.mli
index 9d6baa29c84..f0e9343182c 100644
--- a/src/plugins/eva/Eva.mli
+++ b/src/plugins/eva/Eva.mli
@@ -124,7 +124,7 @@ module Callstack: sig
   module Call : Datatype.S with type t = call
 
   (** Eva callstacks. *)
-  type callstack = Eva_types.Callstack.callstack = {
+  type callstack = {
     thread: int;
     (* An identifier of the thread's callstack. *)
     entry_point: Cil_types.kernel_function;
@@ -133,9 +133,7 @@ module Callstack: sig
     (** A call stack is a list of calls. The head is the latest call. *)
   }
 
-  include Datatype.S_with_collections
-    with type t = callstack
-     and module Hashtbl = Eva_types.Callstack.Hashtbl
+  include Datatype.S_with_collections with type t = callstack
 
   (** Prints a callstack without displaying call sites. *)
   val pretty_short : Format.formatter -> t -> unit
diff --git a/src/plugins/eva/dune b/src/plugins/eva/dune
index 589387e2eda..9a3d06be432 100644
--- a/src/plugins/eva/dune
+++ b/src/plugins/eva/dune
@@ -26,6 +26,8 @@
  (action
   (progn
    (echo "EVA:" %{lib-available:frama-c-eva.core} "\n")
+   (echo " - ppx_deriving.eq:" %{lib-available:ppx_deriving.eq} "\n")
+   (echo " - ppx_deriving.ord:" %{lib-available:ppx_deriving.ord} "\n")
    (echo "Numerors:" %{lib-available:frama-c-eva.numerors.core} "\n")
    (echo " - MLMPFR:" %{lib-available:mlmpfr} "\n")
    (echo "Apron domains:" %{lib-available:frama-c-eva.apron.core} "\n")
@@ -41,7 +43,8 @@
  (flags -open Frama_c_kernel :standard -w -9 -alert -db_deprecated)
  (libraries frama-c.kernel frama-c-server.core)
  (instrumentation (backend landmarks))
- (instrumentation (backend bisect_ppx)))
+ (instrumentation (backend bisect_ppx))
+ (preprocess (staged_pps ppx_deriving.eq ppx_deriving.ord)))
 
 (plugin
  (name eva)
diff --git a/src/plugins/eva/types/callstack.ml b/src/plugins/eva/types/callstack.ml
index 160bfd2d48e..59d31207ef8 100644
--- a/src/plugins/eva/types/callstack.ml
+++ b/src/plugins/eva/types/callstack.ml
@@ -20,4 +20,166 @@
 (*                                                                        *)
 (**************************************************************************)
 
-include Eva_types.Callstack
+let stable_hash x = Hashtbl.seeded_hash 0 x
+
+let dkey_callstack = Kernel.register_category "callstack"
+
+module Thread = Int (* Threads are identified by integers *)
+module Kf = Kernel_function
+module Stmt = Cil_datatype.Stmt
+module Var = Cil_datatype.Varinfo
+
+module Call = Datatype.Pair_with_collections(Kf)(Stmt)
+    (struct let module_name = "Eva.Callstack.Call" end)
+
+module Calls = Datatype.List (Call)
+
+type callstack = {
+  thread: int;
+  entry_point: Kernel_function.t;
+  stack: Call.t list;
+}
+
+module Prototype =
+struct
+  include Datatype.Serializable_undefined
+
+  type t = callstack = {
+    thread: int;
+    entry_point: Kernel_function.t;
+    stack: Call.t list;
+  }
+  [@@deriving eq, ord]
+
+  let name = "Eva.Callstack"
+
+  let reprs =
+    List.concat_map (fun stack ->
+        List.map (fun entry_point -> { thread = 0; entry_point; stack })
+          Kernel_function.reprs)
+      Calls.reprs
+
+  let pretty fmt cs =
+    let pp_call fmt (kf,stmt) =
+      Format.fprintf fmt "%a :: %a <-@ "
+        Kf.pretty kf
+        Cil_datatype.Location.pretty (Stmt.loc stmt)
+    in
+    Format.fprintf fmt "@[<hv>";
+    List.iter (pp_call fmt) cs.stack;
+    Format.fprintf fmt "%a@]" Kernel_function.pretty cs.entry_point
+
+  let hash cs =
+    Hashtbl.hash
+      (cs.thread, Kernel_function.hash cs.entry_point, Calls.hash cs.stack)
+end
+
+type call = Call.t
+
+include Datatype.Make_with_collections (Prototype)
+
+let pretty_debug = pretty
+
+let compare_lex cs1 cs2 =
+  if cs1 == cs2 then 0 else
+    let c = Thread.compare cs1.thread cs2.thread in
+    if c <> 0 then c else
+      let c = Kernel_function.compare cs1.entry_point cs2.entry_point in
+      if c <> 0 then c else
+        Calls.compare (List.rev cs1.stack) (List.rev cs2.stack)
+
+(* Stack manipulation *)
+
+let init ?(thread=0) kf = { thread; entry_point=kf; stack = [] }
+
+let push kf stmt cs =
+  { cs with stack = (kf, stmt) :: cs.stack }
+
+let pop cs =
+  match cs.stack with
+  | [] -> None
+  | _ :: tail -> Some { cs with stack = tail }
+
+let top cs =
+  match cs.stack with
+  | [] -> None
+  | (kf, stmt) :: _ -> Some (kf, stmt)
+
+let top_kf cs =
+  match cs.stack with
+  | (kf, _stmt) :: _ -> kf
+  | [] -> cs.entry_point
+
+let top_callsite cs =
+  match cs.stack with
+  | [] -> Cil_types.Kglobal
+  | (_kf, stmt) :: _ -> Cil_types.Kstmt stmt
+
+let top_call cs =
+  match cs.stack with
+  | (kf, stmt) :: _ -> kf, Cil_types.Kstmt stmt
+  | [] -> cs.entry_point, Cil_types.Kglobal
+
+let top_caller cs =
+  match cs.stack with
+  | _ :: (kf, _) :: _ -> Some kf
+  | [_] -> Some cs.entry_point
+  | [] -> None
+
+(* Conversion *)
+
+let to_kf_list cs = cs.entry_point :: List.rev_map fst cs.stack
+let to_stmt_list cs = List.rev_map snd cs.stack
+
+let to_call_list cs =
+  let l =
+    List.rev_map (fun (kf, stmt) -> (kf, Cil_types.Kstmt stmt)) cs.stack
+  in
+  (cs.entry_point, Cil_types.Kglobal) :: l
+
+(* Stable hash and pretty-printing *)
+
+let stmt_hash s =
+  let pos = fst (Cil_datatype.Stmt.loc s) in
+  stable_hash (pos.Filepath.pos_path, pos.Filepath.pos_lnum)
+
+let kf_hash kf = stable_hash (Kernel_function.get_name kf)
+
+let rec calls_hash = function
+  | [] -> 0
+  | (kf, stmt) :: tl -> stable_hash (kf_hash kf, stmt_hash stmt, calls_hash tl)
+
+let stable_hash { thread; entry_point; stack } =
+  let p = stable_hash (thread, kf_hash entry_point, calls_hash stack) in
+  p mod 11_316_496 (* 58 ** 4 *)
+
+let base58_map = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
+
+(* Converts [i] into a fixed-length, 4-wide string in base-58 *)
+let base58_of_int n =
+  let buf = Bytes.create 4 in
+  Bytes.set buf 0 (String.get base58_map (n mod 58));
+  let n = n / 58 in
+  Bytes.set buf 1 (String.get base58_map (n mod 58));
+  let n = n / 58 in
+  Bytes.set buf 2 (String.get base58_map (n mod 58));
+  let n = n / 58 in
+  Bytes.set buf 3 (String.get base58_map (n mod 58));
+  Bytes.to_string buf
+
+let pretty_hash fmt callstack =
+  if Kernel.is_debug_key_enabled dkey_callstack then
+    Format.fprintf fmt "<%s> " (base58_of_int (stable_hash callstack))
+  else Format.ifprintf fmt ""
+
+let pretty_short fmt callstack =
+  Format.fprintf fmt "%a" pretty_hash callstack;
+  let list = List.rev (to_kf_list callstack) in
+  Pretty_utils.pp_flowlist ~left:"" ~sep:" <- " ~right:""
+    (fun fmt kf -> Kernel_function.pretty fmt kf)
+    fmt list
+
+let pretty fmt callstack =
+  Format.fprintf fmt "@[<hv>%a" pretty_hash callstack;
+  pretty fmt callstack;
+  Format.fprintf fmt "@]"
diff --git a/src/plugins/eva/types/callstack.mli b/src/plugins/eva/types/callstack.mli
index 9e4a7654bbf..76701e429dc 100644
--- a/src/plugins/eva/types/callstack.mli
+++ b/src/plugins/eva/types/callstack.mli
@@ -29,7 +29,7 @@ type call = Cil_types.kernel_function * Cil_types.stmt
 module Call : Datatype.S with type t = call
 
 (** Eva callstacks. *)
-type callstack = Eva_types.Callstack.callstack = {
+type callstack = {
   thread: int;
   (* An identifier of the thread's callstack. *)
   entry_point: Cil_types.kernel_function;
@@ -38,9 +38,7 @@ type callstack = Eva_types.Callstack.callstack = {
   (** A call stack is a list of calls. The head is the latest call. *)
 }
 
-include Datatype.S_with_collections
-  with type t = callstack
-   and module Hashtbl = Eva_types.Callstack.Hashtbl
+include Datatype.S_with_collections with type t = callstack
 
 (** Prints a callstack without displaying call sites. *)
 val pretty_short : Format.formatter -> t -> unit
-- 
GitLab