let data_nodes_visible ff (decl_nodes, data_info) =
    let keep_annots = SlicingParameters.Mode.KeepAnnotations.get () in
    SlicingParameters.debug ~level:2
    "[SlicingTransform.Visibility.data_nodes_visible (with keep_annots = %s)] ?"
      (if keep_annots then "true" else "false");
    let decls_visible = all_nodes_visible ff decl_nodes in
      if keep_annots then decls_visible
      else
        match data_info with
          | None -> raise NoDataInfo
          | Some (data_nodes, data_in) ->
        let is_data_visible visi (n,z) =
          let key = PdgTypes.Node.elem_key n in
          let key = match z, key with
            | Some z, PdgIndex.Key.SigCallKey
                        (call, PdgIndex.Signature.Out
                                 (PdgIndex.Signature.OutLoc out_z)) ->
                let z = Locations.Zone.narrow z out_z in
                  PdgIndex.Key.call_output_key (PdgIndex.Key.call_from_id call) z
            | _, _ -> key
          in
          let m = Fct_slice.get_node_key_mark ff key in
            if !Db.Slicing.Mark.is_bottom m then
              begin
                SlicingParameters.debug ~level:2
                  "[SlicingTransform.Visibility.data_nodes_visible]
                   node %a invisible"

                  (!Db.Pdg.pretty_node true) n;
                false
              end
            else visi
        in
        let visible = decls_visible && data_in_visible ff data_in in
        let data_visible = List.fold_left is_data_visible visible data_nodes in
          data_visible