[IR] Add notion of file captured to procedure attributes.

Reviewed By: jberdine

Differential Revision: D3899826

fbshipit-source-id: 91f063f
master
Cristiano Calcagno 9 years ago committed by Facebook Github Bot 7
parent f30b6e39db
commit bd0215a826

@ -193,19 +193,24 @@ let stats () => {
{num_bindings, num_buckets, max_bucket_length, serialized_size_kb} {num_bindings, num_buckets, max_bucket_length, serialized_size_kb}
}; };
/* Find the file where the procedure is defined according to the attributes, /* Find the file where the procedure was captured, if a cfg for that file exists.
if a cfg for that file exist. */ Return also a boolean indicating whether the procedure is defined in an
let file_defining_procedure pname => include file. */
let find_file_capturing_procedure pname =>
switch (load_attributes pname) { switch (load_attributes pname) {
| None => None | None => None
| Some proc_attributes => | Some proc_attributes =>
let loc = proc_attributes.ProcAttributes.loc; let source_file = proc_attributes.ProcAttributes.source_file_captured;
let source_file = loc.file;
let source_dir = DB.source_dir_from_source_file source_file; let source_dir = DB.source_dir_from_source_file source_file;
let origin =
/* Procedure coming from include files if it has different location
than the file where it was captured. */
DB.source_file_compare source_file proc_attributes.ProcAttributes.loc.file != 0 ?
`Include : `Source;
let cfg_fname = DB.source_dir_get_internal_file source_dir ".cfg"; let cfg_fname = DB.source_dir_get_internal_file source_dir ".cfg";
let cfg_fname_exists = Sys.file_exists (DB.filename_to_string cfg_fname); let cfg_fname_exists = Sys.file_exists (DB.filename_to_string cfg_fname);
if cfg_fname_exists { if cfg_fname_exists {
Some source_file Some (source_file, origin)
} else { } else {
None None
} }

@ -41,9 +41,10 @@ let get_correct_type_from_objc_class_name: Typename.t => option Typ.t;
/** Returns true if the method is defined as a C++ model */ /** Returns true if the method is defined as a C++ model */
let pname_is_cpp_model: Procname.t => bool; let pname_is_cpp_model: Procname.t => bool;
/* Find the file where the procedure is defined according to the attributes, /* Find the file where the procedure was captured, if a cfg for that file exists.
if a cfg for that file exist. */ Return also a boolean indicating whether the procedure is defined in an
let file_defining_procedure: Procname.t => option DB.source_file; include file. */
let find_file_capturing_procedure: Procname.t => option (DB.source_file, [ | `Include | `Source]);
let is_whitelisted_cpp_method: string => bool; let is_whitelisted_cpp_method: string => bool;

@ -1155,17 +1155,19 @@ let save_source_files cfg => {
/** Save the .attr files for the procedures in the cfg. */ /** Save the .attr files for the procedures in the cfg. */
let save_attributes cfg => { let save_attributes source_file cfg => {
let save_proc proc_desc => { let save_proc proc_desc => {
let attributes = Procdesc.get_attributes proc_desc; let attributes = Procdesc.get_attributes proc_desc;
let loc = attributes.ProcAttributes.loc; let loc = attributes.loc;
let attributes' = let attributes' = {
if (Location.equal loc Location.dummy) { let loc' =
let loc' = {...loc, Location.file: !DB.current_source}; if (Location.equal loc Location.dummy) {
{...attributes, ProcAttributes.loc: loc'} {...loc, file: source_file}
} else { } else {
attributes loc
}; };
{...attributes, loc: loc', source_file_captured: source_file}
};
/* /*
L.stderr "save_proc@. proc_name:%a@. filename:%s@. current_source:%s@. loc:%s@." L.stderr "save_proc@. proc_name:%a@. filename:%s@. current_source:%s@. loc:%s@."
Procname.pp (Procdesc.get_proc_name proc_desc) Procname.pp (Procdesc.get_proc_name proc_desc)
@ -1286,7 +1288,11 @@ let inline_java_synthetic_methods cfg => {
/** Save a cfg into a file */ /** Save a cfg into a file */
let store_cfg_to_file save_sources::save_sources=true (filename: DB.filename) (cfg: cfg) => { let store_cfg_to_file
save_sources::save_sources=true
source_file::source_file
(filename: DB.filename)
(cfg: cfg) => {
inline_java_synthetic_methods cfg; inline_java_synthetic_methods cfg;
if save_sources { if save_sources {
save_source_files cfg save_source_files cfg
@ -1297,7 +1303,7 @@ let store_cfg_to_file save_sources::save_sources=true (filename: DB.filename) (c
| None => () | None => ()
} }
}; };
save_attributes cfg; save_attributes source_file cfg;
Serialization.to_file cfg_serializer filename cfg Serialization.to_file cfg_serializer filename cfg
}; };

@ -26,7 +26,8 @@ let load_cfg_from_file: DB.filename => option cfg;
/** Save a cfg into a file, and save a copy of the source files if the boolean is true */ /** Save a cfg into a file, and save a copy of the source files if the boolean is true */
let store_cfg_to_file: save_sources::bool? => DB.filename => cfg => unit; let store_cfg_to_file:
save_sources::bool? => source_file::DB.source_file => DB.filename => cfg => unit;
/** proc description */ /** proc description */

@ -45,7 +45,8 @@ type t = {
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */
ret_type: Typ.t /** return type */ ret_type: Typ.t, /** return type */
source_file_captured: DB.source_file /** source file where the procedure was captured */
}; };
let default proc_name language => { let default proc_name language => {
@ -71,5 +72,6 @@ let default proc_name language => {
objc_accessor: None, objc_accessor: None,
proc_flags: proc_flags_empty (), proc_flags: proc_flags_empty (),
proc_name, proc_name,
ret_type: Typ.Tvoid ret_type: Typ.Tvoid,
source_file_captured: DB.source_file_empty
}; };

@ -39,7 +39,8 @@ type t = {
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */
ret_type: Typ.t /** return type */ ret_type: Typ.t, /** return type */
source_file_captured: DB.source_file /** source file where the procedure was captured */
}; };

@ -77,23 +77,22 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) =
| Some cg -> | Some cg ->
let source = Cg.get_source cg in let source = Cg.get_source cg in
exe_env.source_files <- DB.SourceFileSet.add source exe_env.source_files; exe_env.source_files <- DB.SourceFileSet.add source exe_env.source_files;
let nLOC = Cg.get_nLOC cg in
let file_data = new_file_data source nLOC cg_fname in
let defined_procs = Cg.get_defined_nodes cg in let defined_procs = Cg.get_defined_nodes cg in
IList.iter IList.iter
(fun pname -> (fun pname ->
(match AttributesTable.file_defining_procedure pname with (match AttributesTable.find_file_capturing_procedure pname with
| None -> | None ->
Procname.Hash.replace exe_env.proc_map pname file_data ()
| Some source_defined -> | Some (source_captured, origin) ->
let multiply_defined = DB.source_file_compare source source_defined <> 0 in let multiply_defined = DB.source_file_compare source source_captured <> 0 in
if multiply_defined then Cg.remove_node_defined cg pname; if multiply_defined then Cg.remove_node_defined cg pname;
if Config.check_duplicate_symbols && if Config.check_duplicate_symbols &&
multiply_defined then multiply_defined &&
L.stderr "@.DUPLICATE_SYMBOLS source: %s source_defined:%s pname:%a@." origin <> `Include then
L.stderr "@.DUPLICATE_SYMBOLS source: %s source_captured:%s pname:%a@."
(DB.source_file_to_string source) (DB.source_file_to_string source)
(DB.source_file_to_string source_defined) (DB.source_file_to_string source_captured)
Procname.pp pname Procname.pp pname
)) ))
defined_procs; defined_procs;
@ -114,7 +113,7 @@ let get_file_data exe_env pname =
None None
| Some proc_attributes -> | Some proc_attributes ->
let loc = proc_attributes.ProcAttributes.loc in let loc = proc_attributes.ProcAttributes.loc in
let source_file = loc.Location.file in let source_file = proc_attributes.ProcAttributes.source_file_captured in
let nLOC = loc.Location.nLOC in let nLOC = loc.Location.nLOC in
let source_dir = DB.source_dir_from_source_file source_file in let source_dir = DB.source_dir_from_source_file source_file in
let cg_fname = DB.source_dir_get_internal_file source_dir ".cg" in let cg_fname = DB.source_dir_get_internal_file source_dir ".cg" in

@ -457,10 +457,10 @@ let write_html_proc proof_cover table_nodes_at_linenum global_err_log proc_desc
let process_proc = let process_proc =
Cfg.Procdesc.is_defined proc_desc && Cfg.Procdesc.is_defined proc_desc &&
DB.source_file_equal proc_loc.Location.file !DB.current_source && DB.source_file_equal proc_loc.Location.file !DB.current_source &&
match AttributesTable.file_defining_procedure proc_name with match AttributesTable.find_file_capturing_procedure proc_name with
| None -> true | None -> true
| Some source_file -> | Some (source_captured, _) ->
DB.source_file_equal source_file (Cfg.Procdesc.get_loc proc_desc).file in DB.source_file_equal source_captured (Cfg.Procdesc.get_loc proc_desc).file in
if process_proc then if process_proc then
begin begin
IList.iter (process_node table_nodes_at_linenum) (Cfg.Procdesc.get_nodes proc_desc); IList.iter (process_node table_nodes_at_linenum) (Cfg.Procdesc.get_nodes proc_desc);

@ -71,7 +71,7 @@ let do_source_file source_file ast =
let cfg_file = DB.source_dir_get_internal_file source_dir ".cfg" in let cfg_file = DB.source_dir_get_internal_file source_dir ".cfg" in
let cg_file = DB.source_dir_get_internal_file source_dir ".cg" in let cg_file = DB.source_dir_get_internal_file source_dir ".cg" in
Cg.store_to_file cg_file call_graph; Cg.store_to_file cg_file call_graph;
Cfg.store_cfg_to_file cfg_file cfg; Cfg.store_cfg_to_file ~source_file:!DB.current_source cfg_file cfg;
(*Logging.out "Tenv %a@." Sil.pp_tenv tenv;*) (*Logging.out "Tenv %a@." Sil.pp_tenv tenv;*)
(* Printing.print_tenv tenv; *) (* Printing.print_tenv tenv; *)
(*Printing.print_procedures cfg; *) (*Printing.print_procedures cfg; *)

@ -49,7 +49,7 @@ let store_icfg tenv cg cfg =
let cg_file = DB.source_dir_get_internal_file source_dir ".cg" in let cg_file = DB.source_dir_get_internal_file source_dir ".cg" in
if Config.create_harness then Harness.create_harness cfg cg tenv; if Config.create_harness then Harness.create_harness cfg cg tenv;
Cg.store_to_file cg_file cg; Cg.store_to_file cg_file cg;
Cfg.store_cfg_to_file cfg_file cfg; Cfg.store_cfg_to_file ~source_file:!DB.current_source cfg_file cfg;
if Config.debug_mode || Config.frontend_tests then if Config.debug_mode || Config.frontend_tests then
begin begin
Dotty.print_icfg_dotty cfg; Dotty.print_icfg_dotty cfg;

@ -36,7 +36,7 @@ let store_icfg cg cfg =
let cg_file = get_internal_file ".cg" in let cg_file = get_internal_file ".cg" in
let cfg_file = get_internal_file ".cfg" in let cfg_file = get_internal_file ".cfg" in
Cg.store_to_file cg_file cg; Cg.store_to_file cg_file cg;
Cfg.store_cfg_to_file cfg_file cfg; Cfg.store_cfg_to_file ~source_file:!DB.current_source cfg_file cfg;
if Config.debug_mode || Config.frontend_tests then if Config.debug_mode || Config.frontend_tests then
begin begin
Dotty.print_icfg_dotty cfg; Dotty.print_icfg_dotty cfg;

Loading…
Cancel
Save