let merge_fun_callers get_list get_value merge is_top acc proj kf =
if is_top acc then acc
else begin
let acc = ref acc in
let table = ref Cil_datatype.Varinfo.Set.empty in
try
let merge m =
acc := merge m !acc ;
if is_top !acc then
raise StopMerging
in
let rec merge_fun_callers kf =
let merge_fun_caller (kf,_) = merge_fun_callers kf in
let vf = Kernel_function.get_vi kf in
if not (Cil_datatype.Varinfo.Set.mem vf !table) then begin
table := Cil_datatype.Varinfo.Set.add vf !table ;
List.iter (fun x -> merge (get_value x)) (get_list proj kf) ;
List.iter merge_fun_caller (!Db.Value.callers kf)
end
in
merge_fun_callers kf;
!acc
with StopMerging ->
!acc
end