You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
5.0 KiB

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
module Access : sig
type 'array_index t =
| FieldAccess of Fieldname.t
| ArrayAccess of Typ.t * 'array_index
| TakeAddress
| Dereference
[@@deriving compare]
val pp : (Format.formatter -> 'array_index -> unit) -> Format.formatter -> 'array_index t -> unit
val is_field_or_array_access : 'a t -> bool
end
type t =
| AccessExpression of access_expression (** access path (e.g., x.f.g or x[i]) *)
| UnaryOperator of Unop.t * t * Typ.t option
(** Unary operator with type of the result if known *)
| BinaryOperator of Binop.t * t * t (** Binary operator *)
| Exception of t (** Exception *)
| Closure of Procname.t * (AccessPath.base * t) list (** Name of function + environment *)
| Constant of Const.t (** Constants *)
| Cast of Typ.t * t (** Type cast *)
| Sizeof of Typ.t * t option
(** C-style sizeof(), and also used to treate a type as an expression. Refer to [Exp] module
for canonical documentation *)
and access_expression = private
| Base of AccessPath.base
| FieldOffset of access_expression * Fieldname.t (** field access *)
| ArrayOffset of access_expression * Typ.t * t option (** array access *)
| AddressOf of access_expression (** "address of" operator [&] *)
| Dereference of access_expression (** "dereference" operator [*] *)
[@@deriving compare]
module AccessExpression : sig
val of_id : Ident.t -> Typ.t -> access_expression [@@warning "-32"]
val base : AccessPath.base -> access_expression
val field_offset : access_expression -> Fieldname.t -> access_expression
val array_offset : access_expression -> Typ.t -> t option -> access_expression
val dereference : access_expression -> access_expression
(** guarantees that we never build [Dereference (AddressOf t)] expressions: these become [t] *)
val address_of : access_expression -> access_expression option
[@@warning "-32"]
(** address_of doesn't always make sense, eg [address_of (Dereference t)] is [None] *)
val address_of_base : AccessPath.base -> access_expression [@@warning "-32"]
val to_access_path : access_expression -> AccessPath.t
val get_base : access_expression -> AccessPath.base
val replace_base :
remove_deref_after_base:bool -> AccessPath.base -> access_expression -> access_expression
val is_base : access_expression -> bool
val is_return_var : access_expression -> bool
val get_typ : access_expression -> Tenv.t -> Typ.t option
val pp : Format.formatter -> access_expression -> unit
val equal : access_expression -> access_expression -> bool
val to_accesses : access_expression -> access_expression * t option Access.t list
(** return the base and a list of accesses equivalent to the input expression *)
val add_access : access_expression -> t option Access.t -> access_expression option
val truncate : access_expression -> (access_expression * t option Access.t) option
(** remove and return the prefix and the last access of the expression if it's a base; otherwise
return None *)
val append : onto:access_expression -> access_expression -> access_expression option
(** [append ~onto y] replaces the base of [y] with [onto] itself; this makes sense if no
[Dereference (AddressOf _)] instances are introduced *)
type nonrec t = access_expression = private
| Base of AccessPath.base
| FieldOffset of access_expression * Fieldname.t
| ArrayOffset of access_expression * Typ.t * t option
| AddressOf of access_expression
| Dereference of access_expression
[@@deriving compare]
val fold_vars : (t, Var.t, 'accum) Container.fold
end
val pp : F.formatter -> t -> unit
val get_typ : Tenv.t -> t -> Typ.t option
(** Get the type of the expression. Warning: not fully implemented *)
val of_sil :
include_array_indexes:bool
-> f_resolve_id:(Var.t -> AccessExpression.t option)
-> add_deref:bool
-> Exp.t
-> Typ.t
-> t
(** Convert SIL expression to HIL expression *)
val get_access_exprs : t -> AccessExpression.t list
(** Get all the access paths used in the given HIL expression, including duplicates if a path is
used more than once. *)
val is_null_literal : t -> bool
val is_int_zero : t -> bool
val eval : t -> Const.t option
val eval_boolean_exp : AccessExpression.t -> t -> bool option
(** [eval_boolean_exp var exp] returns [Some bool_value] if the given boolean expression [exp]
evaluates to [bool_value] when [var] is set to true. Return None if it has free variables that
stop us from evaluating it, or is not a boolean expression. *)
val ignore_cast : t -> t
val access_expr_of_exp :
include_array_indexes:bool
-> f_resolve_id:(Var.t -> AccessExpression.t option)
-> Exp.t
-> Typ.t
-> access_expression option
(** best effort translating a SIL expression to an access path, not semantics preserving in
particular in the presence of pointer arithmetic *)