(****************************************************************************)
(*                                                                          *)
(*  Copyright (C) 2001-2003                                                 *)
(*   George C. Necula    <necula@cs.berkeley.edu>                           *)
(*   Scott McPeak        <smcpeak@cs.berkeley.edu>                          *)
(*   Wes Weimer          <weimer@cs.berkeley.edu>                           *)
(*   Ben Liblit          <liblit@cs.berkeley.edu>                           *)
(*  All rights reserved.                                                    *)
(*                                                                          *)
(*  Redistribution and use in source and binary forms, with or without      *)
(*  modification, are permitted provided that the following conditions      *)
(*  are met:                                                                *)
(*                                                                          *)
(*  1. Redistributions of source code must retain the above copyright       *)
(*  notice, this list of conditions and the following disclaimer.           *)
(*                                                                          *)
(*  2. Redistributions in binary form must reproduce the above copyright    *)
(*  notice, this list of conditions and the following disclaimer in the     *)
(*  documentation and/or other materials provided with the distribution.    *)
(*                                                                          *)
(*  3. The names of the contributors may not be used to endorse or          *)
(*  promote products derived from this software without specific prior      *)
(*  written permission.                                                     *)
(*                                                                          *)
(*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *)
(*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       *)
(*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       *)
(*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          *)
(*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,     *)
(*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,    *)
(*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;        *)
(*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER        *)
(*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT      *)
(*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN       *)
(*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         *)
(*  POSSIBILITY OF SUCH DAMAGE.                                             *)
(*                                                                          *)
(*  File modified by CEA (Commissariat à l'énergie atomique et aux          *)
(*                        énergies alternatives)                            *)
(*               and INRIA (Institut National de Recherche en Informatique  *)
(*                          et Automatique).                                *)
(****************************************************************************)

(** Smart constructors for some CIL data types *)
open Cil_types

val voidType: typ

(** forward reference to current location (see {!Cil.CurrentLoc})*)
module CurrentLoc: State_builder.Ref with type data = location

module Vid: sig val next: unit -> int end
module Sid: sig val next: unit -> int end
module Eid: sig val next: unit -> int end

(** set the vid to a fresh number. *)
val set_vid: varinfo -> unit

(** returns a copy of the varinfo with a fresh vid.
    If the varinfo has an associated logic var, a copy of the logic var
    is made as well.
    @modify Oxygen-20120901 take logic var into account
*)
val copy_with_new_vid: varinfo -> varinfo

(** [change_varinfo_name vi name] changes the name of [vi] to [name]. Takes
    care of renaming the associated logic_var if any.
    @since Oxygen-20120901
*)
val change_varinfo_name: varinfo -> string -> unit

val new_raw_id: unit -> int
  (** Generate a new ID. This will be different than any variable ID
      that is generated by {!Cil.makeLocalVar} and friends.
      Must not be used for setting vid: use {!set_vid} instead. *)

(** Creates a (potentially recursive) composite type. The arguments are:
 * (1) a boolean indicating whether it is a struct or a union, (2) the name
 * (always non-empty), (3) a function that when given a representation of the
 * structure type constructs the type of the fields recursive type (the first
 * argument is only useful when some fields need to refer to the type of the
 * structure itself), and (4) a list of attributes to be associated with the
 * composite type. The resulting compinfo has the field "cdefined" only if
 * the list of fields is non-empty. *)
val mkCompInfo: bool ->      (* whether it is a struct or a union *)
               string -> (* name of the composite type; cannot be empty *)
               ?norig:string -> (* original name of the composite type, empty when anonymous *)
               (compinfo ->
                  (string * typ * int option * attributes * location) list) ->
               (* a function that when given a forward
                  representation of the structure type constructs the type of
                  the fields. The function can ignore this argument if not
                  constructing a recursive type.  *)
               attributes -> compinfo

(** Makes a shallow copy of a {!Cil_types.compinfo} changing the name. It also
    copies the fields, and makes sure that the copied field points back to the
    copied compinfo.
    If [fresh] is [true] (the default), it will also give a fresh id to the
    copy.
*)
val copyCompInfo: ?fresh:bool -> compinfo -> string -> compinfo


(** Create a fresh logical variable giving its name, type and origin.
    @since Fluorine-20130401
*)
val make_logic_var_kind : string -> logic_var_kind -> logic_type -> logic_var

(** Create a fresh logical variable giving its name and type. 
    @deprecated Fluorine-20130401 You should use a specific 
    make_logic_var_[kind] function below, or {! Cil.cvar_to_lvar}
*)
val make_logic_var : string -> logic_type -> logic_var

(** Create a new global logic variable 
    @since Fluorine-20130401 *)
val make_logic_var_global: string -> logic_type -> logic_var

(** Create a new formal logic variable 
    @since Fluorine-20130401 *)
val make_logic_var_formal: string -> logic_type -> logic_var

(** Create a new quantified logic variable 
    @since Fluorine-20130401 *)
val make_logic_var_quant: string -> logic_type -> logic_var

(** Create a new local logic variable 
    @since Fluorine-20130401 *)
val make_logic_var_local: string -> logic_type -> logic_var

(** Create a fresh logical (global) variable giving its name and type. *)
val make_logic_info : string -> (* logic_type -> *) logic_info

(** Create a new local logic variable given its name.
    @since Fluorine-20130401
*)
val make_logic_info_local : string -> (* logic_type -> *) logic_info

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