parent
							
								
									c9f07e31e3
								
							
						
					
					
						commit
						d7655a087e
					
				| @ -0,0 +1,102 @@ | |||||||
|  | (* | ||||||
|  | * Copyright (c) 2015 - present Facebook, Inc. | ||||||
|  | * All rights reserved. | ||||||
|  | * | ||||||
|  | * This source code is licensed under the BSD style license found in the | ||||||
|  | * LICENSE file in the root directory of this source tree. An additional grant | ||||||
|  | * of patent rights can be found in the PATENTS file in the same directory. | ||||||
|  | *) | ||||||
|  | 
 | ||||||
|  | open Utils | ||||||
|  | 
 | ||||||
|  | type procedure_type = | ||||||
|  |   | ALL | ||||||
|  |   | DEFINED | ||||||
|  |   | OBJC_GENERATED | ||||||
|  | 
 | ||||||
|  | let print_map procname_map = | ||||||
|  |   Procname.Hash.iter | ||||||
|  |     (fun pname redefined -> | ||||||
|  |           print_endline ((Procname.to_string pname)^" "^(string_of_bool redefined))) | ||||||
|  |     procname_map | ||||||
|  | 
 | ||||||
|  | let process_all_cfgs process_function default_value = | ||||||
|  |   let source_dirs = DB.find_source_dirs () in | ||||||
|  |   let process_dir source_dir value = | ||||||
|  |     let cfg_name = DB.source_dir_get_internal_file source_dir ".cfg" in | ||||||
|  |     let cfg_opt = Cfg.load_cfg_from_file cfg_name in | ||||||
|  |     match cfg_opt with | ||||||
|  |     | None -> value | ||||||
|  |     | Some cfg -> process_function cfg source_dir in | ||||||
|  |   list_fold_right process_dir source_dirs default_value | ||||||
|  | 
 | ||||||
|  | let process_procedures process_function default_value procedure_type = | ||||||
|  |   let process_cfg_procedures cfg source_dir = | ||||||
|  |     let procdescs = | ||||||
|  |       match procedure_type with | ||||||
|  |       | DEFINED -> Cfg.get_defined_procs cfg | ||||||
|  |       | ALL -> Cfg.get_all_procs cfg | ||||||
|  |       | OBJC_GENERATED -> Cfg.get_objc_generated_procs cfg in | ||||||
|  |     list_fold_right (process_function cfg source_dir) procdescs default_value in | ||||||
|  |   process_all_cfgs process_cfg_procedures default_value | ||||||
|  | 
 | ||||||
|  | let process_all_procedures process_function default_value = | ||||||
|  |   process_procedures process_function default_value ALL | ||||||
|  | 
 | ||||||
|  | let process_defined_procedures process_function default_value = | ||||||
|  |   process_procedures process_function default_value DEFINED | ||||||
|  | 
 | ||||||
|  | let process_objc_generated_procedures process_function default_value = | ||||||
|  |   process_procedures process_function default_value OBJC_GENERATED | ||||||
|  | 
 | ||||||
|  | (* first run to fill the map. The bool that indicates whether the method *) | ||||||
|  | (* has a real implementation is false by default *) | ||||||
|  | let fill_generated_proc_map generated_proc_map = | ||||||
|  |   let add_generated_pname_to_map cfg source_dir procdesc () = | ||||||
|  |     let pname = Cfg.Procdesc.get_proc_name procdesc in | ||||||
|  |     Procname.Hash.replace generated_proc_map pname false in | ||||||
|  |   process_objc_generated_procedures add_generated_pname_to_map () | ||||||
|  | 
 | ||||||
|  | (* second run to update the map. Now we check whether there is a real *) | ||||||
|  | (* implementation for the generated methods *) | ||||||
|  | let update_generate_proc_map generated_proc_map = | ||||||
|  |   let update_generated_pname_to_map cfg source_dir procdesc () = | ||||||
|  |     let cfg_pname = Cfg.Procdesc.get_proc_name procdesc in | ||||||
|  |     if not (Cfg.Procdesc.get_attributes procdesc).Sil.is_generated then | ||||||
|  |       try ignore(Procname.Hash.find generated_proc_map cfg_pname); | ||||||
|  |         Procname.Hash.replace generated_proc_map cfg_pname true | ||||||
|  |       with Not_found -> () in | ||||||
|  |   process_defined_procedures update_generated_pname_to_map () | ||||||
|  | 
 | ||||||
|  | (* third run to change the cfgs according to the map. The generated methods *) | ||||||
|  | (* that have implementations  get deleted. *) | ||||||
|  | let update_cfgs generated_proc_map = | ||||||
|  |   let update_cfg cfg source_dir = | ||||||
|  |     let generated_procs = Cfg.get_objc_generated_procs cfg in | ||||||
|  |     let cfg_name = DB.source_dir_get_internal_file source_dir ".cfg" in | ||||||
|  |     let cg_name = DB.source_dir_get_internal_file source_dir ".cg" in | ||||||
|  |     let cg_opt = Cg.load_from_file cg_name in | ||||||
|  |     match cg_opt with | ||||||
|  |     | None -> assert false | ||||||
|  |     | Some cg -> | ||||||
|  |         let update_cfg_procdesc procdesc need_updating = | ||||||
|  |           let pname = Cfg.Procdesc.get_proc_name procdesc in | ||||||
|  |           let is_redefined = | ||||||
|  |             try Procname.Hash.find generated_proc_map pname | ||||||
|  |             with Not_found -> assert false in | ||||||
|  |           if is_redefined then | ||||||
|  |             (Cfg.Procdesc.remove cfg pname true; | ||||||
|  |               Cg.node_set_defined cg pname false; | ||||||
|  |               true) | ||||||
|  |           else need_updating in | ||||||
|  |         let need_updating = list_fold_right update_cfg_procdesc generated_procs false in | ||||||
|  |         if need_updating then | ||||||
|  |           (Cfg.store_cfg_to_file cfg_name false cfg; | ||||||
|  |             Cg.store_to_file cg_name cg) in | ||||||
|  |   process_all_cfgs update_cfg () | ||||||
|  | 
 | ||||||
|  | let do_objc_preanalysis () = | ||||||
|  |   let generated_proc_map = Procname.Hash.create 100 in | ||||||
|  |   fill_generated_proc_map generated_proc_map; | ||||||
|  |   update_generate_proc_map generated_proc_map; | ||||||
|  |   update_cfgs generated_proc_map | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | (* | ||||||
|  | * Copyright (c) 2015 - present Facebook, Inc. | ||||||
|  | * All rights reserved. | ||||||
|  | * | ||||||
|  | * This source code is licensed under the BSD style license found in the | ||||||
|  | * LICENSE file in the root directory of this source tree. An additional grant | ||||||
|  | * of patent rights can be found in the PATENTS file in the same directory. | ||||||
|  | *) | ||||||
|  | 
 | ||||||
|  | val do_objc_preanalysis : unit -> unit | ||||||
| @ -1,24 +0,0 @@ | |||||||
| digraph iCFG { |  | ||||||
| 6 [label="6:  BinaryOperatorStmt: Assign \n   n$2=*&self:class Test * [line 14]\n  n$3=*&numberOfFiles:int  [line 14]\n  *n$2.numberOfFiles:int =n$3 [line -1]\n  REMOVE_TEMPS(n$2,n$3); [line -1]\n  NULLIFY(&numberOfFiles,false); [line -1]\n  NULLIFY(&self,false); [line -1]\n  APPLY_ABSTRACTION; [line -1]\n " shape="box"] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 	 6 -> 5 ; |  | ||||||
| 5 [label="5: Exit Test_setNumberOfFiles: \n  " color=yellow style=filled] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 4 [label="4: Start Test_setNumberOfFiles:\nFormals:  self:class Test * numberOfFiles:int \nLocals:  \n   DECLARE_LOCALS(&return); [line -1]\n " color=yellow style=filled] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 	 4 -> 6 ; |  | ||||||
| 3 [label="3:  Return Stmt \n   n$0=*&self:class Test * [line -1]\n  n$1=*n$0.numberOfFiles:int  [line -1]\n  *&return:int =n$1 [line -1]\n  REMOVE_TEMPS(n$0,n$1); [line -1]\n  NULLIFY(&self,false); [line -1]\n  APPLY_ABSTRACTION; [line -1]\n " shape="box"] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 	 3 -> 2 ; |  | ||||||
| 2 [label="2: Exit Test_numberOfFiles \n  " color=yellow style=filled] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 1 [label="1: Start Test_numberOfFiles\nFormals:  self:class Test *\nLocals:  \n   DECLARE_LOCALS(&return); [line -1]\n " color=yellow style=filled] |  | ||||||
| 	 |  | ||||||
| 
 |  | ||||||
| 	 1 -> 3 ; |  | ||||||
| } |  | ||||||
					Loading…
					
					
				
		Reference in new issue