(**************************************************************************)
(*                                                                        *)
(*  This file is part of the Frama-C's E-ACSL plug-in.                    *)
(*                                                                        *)
(*  Copyright (C) 2012-2020                                               *)
(*    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).            *)
(*                                                                        *)
(**************************************************************************)

open Cil_types

val has_fundef: exp -> bool
(** @return [true] if a function whose name is given via [exp] is defined and
    [false] otherwise *)

val check: kernel_function -> bool
(** @return [true] iff code must be generated for annotations of the given
    function. *)

val instrument: kernel_function -> bool
(** @return [true] iff the given function must be instrumented. *)

(* ************************************************************************** *)
(** {2 RTL} Operations on function belonging to the runtime library of E-ACSL *)
(* ************************************************************************** *)

module RTL: sig

  val mk_api_name: string -> string
  (** Prefix a name (of a variable or a function) with a string that identifies
      it as belonging to the public API of E-ACSL runtime library *)

  val mk_temporal_name: string -> string
  (** Prefix a name (of a variable or a function) with a string that identifies
      it as belonging to the public API of E-ACSL runtime library dealing
      with temporal analysis. *)

  val mk_gen_name: string -> string
  (** Prefix a name (of a variable or a function) with a string indicating
      that this name has been generated during instrumentation phase. *)

  val is_generated_name: string -> bool
  (** @return [true] if the prefix of the given name indicates that it has been
      generated by E-ACSL instrumentation (see [mk_gen_name] function). *)

  val is_generated_kf: kernel_function -> bool
  (** Same as [is_generated_name] but for kernel functions *)

  val is_generated_literal_string_name: string -> bool
  (** Same as [is_generated_name] but indicates that the name represents a local
      variable that replaced a literal string. *)

  val get_original_name: kernel_function -> string
  (** Retrieve the name of the kernel function and strip prefix that indicates
      that it has been generated by the instrumentation. *)

  val libc_replacement_name: string -> string
  (** Given the name of C library function return the name of the RTL function
      that potentially replaces it. *)

  val has_rtl_replacement: string -> bool
  (** Given the name of C library function return true if there is a drop-in
      replacement function for it in the RTL. *)

end (* Rtl *)

(* ************************************************************************** *)
(** {2 Libc} Operations on functions belonging to standard library *)
(* ************************************************************************** *)

module Libc: sig

  val is_memcpy: exp -> bool
  (** Return [true] if [exp] captures a function name that matches [memcpy] or
      an equivalent function *)

  val is_memcpy_name: string -> bool
  (** Same as [is_memcpy] but for strings *)

  val is_memset: exp -> bool
  (** Return [true] if [exp] captures a function name that matches [memset] or
      an equivalent function *)

  val is_memset_name: string -> bool
  (** Same as [is_memset] but for strings *)

  val is_dyn_alloc: exp -> bool
  (** Return [true] if [exp] captures a function name that matches a function
      that dynamically allocates memory such as [malloc] or [calloc] *)

  val is_dyn_alloc_name: string -> bool
  (** Same as [is_dyn_alloc] but for strings *)

  val is_dyn_free: exp -> bool
  (** Return [true] if [exp] captures a function name that matches
      a function that dynamically deallocates memory (e.g., [free]) *)

  val is_dyn_free_name: string -> bool
  (** Same as [is_dyn_free] but for strings *)

  val is_vla_free: exp -> bool
  (** Return [true] if [exp] captures a function name that matches
      a function that allocates memory for a variable-size array. *)

  val is_vla_free_name: string -> bool
  (** Return [true] if [string] captures a function name that matches
      a function that deallocates memory for a variable-size array. *)

  val is_vla_alloc: exp -> bool
  (** Return [true] if [exp] captures a function name that matches
      a function that deallocates memory for a variable-size array. *)

  val is_vla_alloc_name: string -> bool
  (** Same as [is_dyn_alloc] but for strings *)

  val is_alloca: exp -> bool
  (** Return [true] if [exp] captures a function name that matches
      a function that allocates memory on stack. *)

  val is_alloca_name: string -> bool
  (** Same as [is_alloca] but for strings *)

  val is_printf: exp -> bool
  (** Return [true] if [exp] captures a function name that matches
      a printf-like function such as [printf], [fprintf], [dprintf] etc. *)

  val is_printf_name: string -> bool
  (** Same as [is_printf] but for strings *)

  val printf_fmt_position: string -> int
  (** Given the name of a printf-like function (as determined by
      [is_printf_name]) return the number of arguments preceding its variadic
      arguments. *)

  val get_printf_argument_str: loc:location -> string -> exp list -> exp
  (** Given the name of a printf-like function and the list of its variadic
      arguments return a literal string expression where each character
      describes the type of an argument from a list. Such characters are also
      called abbreviated types. Conversion between abbreviated and C types
      characters is as follows:
      -  "b" -> [_Bool]
      -  "c" -> [signed char]
      -  "C" -> [unsigned char]
      -  "d" -> [int]
      -  "D" -> [unsigned int]
      -  "h" -> [short]
      -  "H" -> [unsigned short]
      -  "l" -> [long]
      -  "L" -> [unsigned long]
      -  "r" -> [long long]
      -  "R" -> [unsigned long long]
      -  "f" -> [float]
      -  "e" -> [double]
      -  "E" -> [long double]
      -  "s" -> [char*]
      -  "i" -> [int*]
      -  "p" -> [void*] *)

  val actual_alloca: string
  (** The name of an actual [alloca] function used at link-time.
      In GCC/Clang [alloca] is typically implemented via [__builtin_alloca] *)

end (* Libc *)

(*
Local Variables:
compile-command: "make -C ../../../../.."
End:
*)
