let process_call pdg state stmt lvaloption funcexp argl =
  let state_before_call = state in
  let _ = BuildPdg.process_call_node pdg stmt in
  let arg_nodes = process_args pdg state_before_call stmt argl in
  let state_with_args = state in
  let funcexp_dpds, called_functions =
    !Db.Value.expr_to_kernel_function
       ~with_alarms:CilE.warn_none_mode
      (Kstmt stmt) ~deps:(Some Locations.Zone.bottom) funcexp
  in
  let mixed_froms =
    try let froms = !Db.From.Callwise.find (Kstmt stmt) in Some froms
    with Not_found -> None (* don't have callwise analysis (-calldeps option) *)
  in
  let process_simple_call called_kf acc =
    let state_with_inputs =
      BuildPdg.process_call_params pdg state_with_args stmt called_kf arg_nodes
    in
    let r =
      match mixed_froms with
        | Some _ -> state_with_inputs (* process outputs later *)
        | None -> (* don't have callwise analysis (-calldeps option) *)
            let froms = !Db.From.get called_kf in
            let state_for_this_call =
              call_ouputs pdg state_before_call state_with_inputs
                stmt lvaloption froms funcexp_dpds
            in state_for_this_call
    in r :: acc
  in
  let state_for_each_call =
    Kernel_function.Hptset.fold process_simple_call called_functions []
  in
  let new_state =
    match state_for_each_call with
    | [] ->
       let stmt_str = Pretty_utils.sfprintf "%a" !Ast_printer.d_stmt stmt in
       Extlib.not_yet_implemented
         ("pdg with an unknown function call : " ^ stmt_str)
    | st :: [] -> st
    | st :: other_states ->
        let merge s1 s2 =
          let _,s = BuildPdg.test_and_merge_states ~old:s1 s2 in s
        in List.fold_left merge st other_states
  in
  let new_state = match mixed_froms with
    | None -> new_state
    | Some froms ->
          call_ouputs pdg state_before_call new_state
            stmt lvaloption froms funcexp_dpds
  in
  Some new_state