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.
100 lines
3.9 KiB
100 lines
3.9 KiB
(*
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*)
|
|
|
|
open! IStd
|
|
|
|
(** Process variable declarations by saving them as local or global variables. *)
|
|
|
|
(** Computes the local variables of a function or method to be added to the procdesc *)
|
|
|
|
let is_custom_var_pointer pointer = pointer <= 0
|
|
|
|
let sil_var_of_decl context var_decl procname =
|
|
let outer_procname = CContext.get_outer_procname context in
|
|
let trans_unit_ctx = context.CContext.translation_unit_context in
|
|
let open Clang_ast_t in
|
|
match var_decl with
|
|
| VarDecl (decl_info, name_info, qual_type, var_decl_info) ->
|
|
let shoud_be_mangled = not (is_custom_var_pointer decl_info.Clang_ast_t.di_pointer) in
|
|
let var_decl_details = Some (decl_info, qual_type, var_decl_info, shoud_be_mangled) in
|
|
CGeneral_utils.mk_sil_var trans_unit_ctx name_info var_decl_details procname outer_procname
|
|
| ParmVarDecl (decl_info, name_info, qual_type, var_decl_info) ->
|
|
let var_decl_details = Some (decl_info, qual_type, var_decl_info, false) in
|
|
CGeneral_utils.mk_sil_var trans_unit_ctx name_info var_decl_details procname outer_procname
|
|
| _ ->
|
|
assert false
|
|
|
|
|
|
let sil_var_of_decl_ref context source_range decl_ref procname =
|
|
let name =
|
|
match decl_ref.Clang_ast_t.dr_name with Some name_info -> name_info | None -> assert false
|
|
in
|
|
match decl_ref.Clang_ast_t.dr_kind with
|
|
| `ImplicitParam ->
|
|
let outer_procname = CContext.get_outer_procname context in
|
|
let trans_unit_ctx = context.CContext.translation_unit_context in
|
|
CGeneral_utils.mk_sil_var trans_unit_ctx name None procname outer_procname
|
|
| _ ->
|
|
let pointer = decl_ref.Clang_ast_t.dr_decl_pointer in
|
|
if is_custom_var_pointer pointer then
|
|
Pvar.mk (Mangled.from_string name.Clang_ast_t.ni_name) procname
|
|
else
|
|
match CAst_utils.get_decl pointer with
|
|
| Some var_decl ->
|
|
sil_var_of_decl context var_decl procname
|
|
| None ->
|
|
(* FIXME(t21762295) *)
|
|
CFrontend_config.incorrect_assumption __POS__ source_range
|
|
"pointer '%d' for var decl not found. The var decl was: %a" pointer
|
|
(Pp.to_string ~f:Clang_ast_j.string_of_decl_ref)
|
|
decl_ref
|
|
|
|
|
|
let get_var_attribute decl_info =
|
|
let open Clang_ast_t in
|
|
let has_block_attribute =
|
|
List.exists decl_info.Clang_ast_t.di_attributes ~f:(fun attr ->
|
|
match attr with BlocksAttr _ -> true | _ -> false )
|
|
in
|
|
if has_block_attribute then [ProcAttributes.Modify_in_block] else []
|
|
|
|
|
|
let add_var_to_locals procdesc var_decl typ pvar =
|
|
let open Clang_ast_t in
|
|
match var_decl with
|
|
| VarDecl (decl_info, _, _, vdi) ->
|
|
if not vdi.Clang_ast_t.vdi_is_global then
|
|
let attributes = get_var_attribute decl_info in
|
|
let var_data : ProcAttributes.var_data = {name= Pvar.get_name pvar; typ; attributes} in
|
|
Procdesc.append_locals procdesc [var_data]
|
|
| _ ->
|
|
assert false
|
|
|
|
|
|
let sil_var_of_captured_var decl_ref context source_range procname =
|
|
match decl_ref with
|
|
| {Clang_ast_t.dr_qual_type= Some qual_type} ->
|
|
( sil_var_of_decl_ref context source_range decl_ref procname
|
|
, CType_decl.qual_type_to_sil_type context.CContext.tenv qual_type )
|
|
| _ ->
|
|
assert false
|
|
|
|
|
|
(* Returns a list of captured variables as sil variables. *)
|
|
let captured_vars_from_block_info context source_range cvl =
|
|
let procname = Procdesc.get_proc_name context.CContext.procdesc in
|
|
let sil_var_of_captured_var {Clang_ast_t.bcv_variable} vars_acc =
|
|
match bcv_variable with
|
|
| Some ({Clang_ast_t.dr_name= Some {Clang_ast_t.ni_name}} as decl_ref) ->
|
|
if String.equal ni_name CFrontend_config.self && not (CContext.is_objc_instance context)
|
|
then vars_acc
|
|
else sil_var_of_captured_var decl_ref context source_range procname :: vars_acc
|
|
| _ ->
|
|
assert false
|
|
in
|
|
List.fold_right ~f:sil_var_of_captured_var cvl ~init:[]
|