ClangFrontend.CTrans_utils
Utility methods to support the translation of clang ast constructs into sil instructions.
type continuation = {
break : IR.Procdesc.Node.t list;
continue : IR.Procdesc.Node.t list;
return_temp : bool;
true if temps should not be removed in the node but returned to ancestors
*)}
type priority_node =
| Free
no node currently being created
*)| Busy of ATDGenerated.Clang_ast_t.pointer
the translation of the clang expression or statement at pointer
will create a node with the collected instructions from the sub-expressions (see control.instrs
Whether we are collecting instructions for a new block in the CFG (Busy
) or there are no blocks being created from enclosing translations (Free
)
type trans_state = {
context : CContext.t;
global context of the translation
*)succ_nodes : IR.Procdesc.Node.t list;
successor nodes in the CFG, i.e. instructions that will happen *after* the current expression or statement being translated (note that the CFG is constructed bottom-up, starting from the last instructions)
*)continuation : continuation option;
current continuation, used for break
, continue
, and the like
priority : priority_node;
var_exp_typ : (IR.Exp.t * IR.Typ.t) option;
the expression (usually of the form Exp.Lvar pvar
) that the enclosing expression or statement is trying to initialize, if any
opaque_exp : (IR.Exp.t * IR.Typ.t) option;
needed for translating OpaqueValueExpr
nodes
is_fst_arg_objc_instance_method_call : bool;
block_as_arg_attributes : IR.ProcAttributes.block_as_arg_attributes option;
}
The input of the translation constructed from enclosing expressions.
val pp_trans_state : F.formatter -> trans_state -> unit
val default_trans_state : CContext.t -> trans_state
type control = {
root_nodes : IR.Procdesc.Node.t list;
Top cfg nodes (root) created by the translation
*)leaf_nodes : IR.Procdesc.Node.t list;
Bottom cfg nodes (leaf) created by the translate
*)instrs : IR.Sil.instr list;
Instructions that need to be placed in the current CFG node being constructed, *after* leaf_nodes
.
initd_exps : IR.Exp.t list;
list of expressions that are initialized by the instructions
*)cxx_temporary_markers_set : IR.Pvar.t list;
markers for C++ temporaries that have been set during the translation; used to avoid adding the same marker several times
*)}
Part of the translation result that is (loosely) related to control flow graph construction. More importantly, this is the part of a trans_result
that some internal translation functions work on when constructing a trans_result
before the other components of the translation result are available (such as the return expression). This is made into a separate type to make intermediate computations easier to write and easier to typecheck.
val pp_control : F.formatter -> control -> unit
type trans_result = {
control : control;
return : IR.Exp.t * IR.Typ.t;
value returned by the translated statement
*)method_name : IR.Procname.t option;
in the specific case of translating a method call in C++, we get the method name called at the same time we get the this
object that contains the method. The this
instance object is returned as the return
field, while the method to call is filled in here. This field is None
in all other cases.
method_signature : CMethodSignature.t option;
in the specific case of translating a function call, we get the method signature. This field is None
in all other cases.
is_cpp_call_virtual : bool;
}
A translation result. It is returned by the translation function.
val empty_control : control
val mk_trans_result :
?method_name:IR.Procname.t ->
?method_signature:CMethodSignature.t ->
?is_cpp_call_virtual:bool ->
(IR.Exp.t * IR.Typ.t) ->
control ->
trans_result
val undefined_expression : unit -> IR.Exp.t
val collect_controls : IR.Procdesc.t -> control list -> control
Collect the results of translating a list of instructions, and link up the nodes created.
val collect_trans_results :
IR.Procdesc.t ->
return:(IR.Exp.t * IR.Typ.t) ->
trans_result list ->
trans_result
val is_return_temp : continuation option -> bool
val mk_cond_continuation : continuation option -> continuation option
val define_condition_side_effects :
(IR.Exp.t * IR.Typ.t) ->
IR.Sil.instr list ->
IBase.Location.t ->
(IR.Exp.t * IR.Typ.t) * IR.Sil.instr list
val source_range_of_stmt :
ATDGenerated.Clang_ast_t.stmt ->
ATDGenerated.Clang_ast_t.source_range
val extract_stmt_from_singleton :
ATDGenerated.Clang_ast_t.stmt list ->
ATDGenerated.Clang_ast_t.source_range ->
string ->
ATDGenerated.Clang_ast_t.stmt
val is_null_stmt : ATDGenerated.Clang_ast_t.stmt -> bool
val dereference_var_sil :
(IR.Exp.t * IR.Typ.t) ->
IBase.Location.t ->
IR.Sil.instr * IR.Exp.t
val dereference_value_from_result :
?strip_pointer:bool ->
ATDGenerated.Clang_ast_t.source_range ->
IBase.Location.t ->
trans_result ->
trans_result
Given a trans_result
, create a temporary variable with dereferenced value of an expression assigned to it
val cast_operation :
?objc_bridge_cast_kind:ATDGenerated.Clang_ast_t.obj_c_bridge_cast_kind ->
ATDGenerated.Clang_ast_t.cast_kind ->
(IR.Exp.t * IR.Typ.t) ->
IR.Typ.t ->
IBase.Location.t ->
IR.Sil.instr list * (IR.Exp.t * IR.Typ.t)
val trans_assertion : trans_state -> IBase.Location.t -> trans_result
val contains_opaque_value_expr : ATDGenerated.Clang_ast_t.stmt -> bool
val builtin_trans :
trans_state ->
ATDGenerated.Clang_ast_t.source_range ->
IBase.Location.t ->
trans_result list ->
IR.Procname.t ->
trans_result option
val cxx_method_builtin_trans :
trans_state ->
ATDGenerated.Clang_ast_t.source_range ->
IBase.Location.t ->
trans_result list ->
IR.Procname.t ->
trans_result option
val new_or_alloc_trans :
trans_state ->
IBase.Location.t ->
ATDGenerated.Clang_ast_t.stmt_info ->
IR.Typ.t ->
IR.Typ.Name.t option ->
string ->
trans_result
val cpp_new_trans :
IR.IntegerWidths.t ->
IBase.Location.t ->
IR.Typ.t ->
IR.Exp.t option ->
(IR.Exp.t * IR.Typ.t) list ->
trans_result
module Nodes : sig ... end
Module for creating cfg nodes and other utility functions related to them.
module PriorityNode : sig ... end
priority_node is used to enforce some kind of policy for creating nodes in the cfg. Certain elements of the AST _must_ create nodes therefore there is no need for them to use priority_node. Certain elements instead need or need not to create a node depending of certain factors. When an element of the latter kind wants to create a node it must claim priority first (like taking a lock). priority can be claimes only when it is free. If an element of AST succedes in claiming priority its id (pointer) is recorded in priority. After an element has finished it frees the priority. In general an AST element E checks if an ancestor has claimed priority. If priority is already claimed E does not have to create a node. If priority is free then it means E has to create the node. Then E claims priority and release it afterward.
module GotoLabel : sig ... end
Module for translating goto instructions by keeping a map of labels.
module Loops : sig ... end
Module that provides utility functions for translating different types of loops.
module Self : sig ... end
This module handles the translation of the variable self which is challenging because self is used both as a variable in instance method calls and also as a type in class method calls.
val is_logical_negation_of_int :
IR.Tenv.t ->
ATDGenerated.Clang_ast_t.expr_info ->
ATDGenerated.Clang_ast_t.unary_operator_info ->
bool
val mk_fresh_void_id_typ : unit -> IR.Ident.t * IR.Typ.t
val mk_fresh_void_return :
unit ->
(IR.Ident.t * IR.Typ.t) * (IR.Exp.t * IR.Typ.t)
val should_remove_first_param :
trans_state ->
ATDGenerated.Clang_ast_t.stmt ->
IR.Typ.name option
Return a class name when the first parameter should be removed according to its context, for example, when self
or [x class]
is given as the first parameter for a class method.