~ubuntu-branches/debian/sid/frama-c/sid

« back to all changes in this revision

Viewing changes to src/slicing/slicingMacros.ml

  • Committer: Bazaar Package Importer
  • Author(s): Mehdi Dogguy
  • Date: 2009-06-03 08:19:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090603081925-kihvxvt0wy3zc4ar
Tags: upstream-20081201.dfsg
Import upstream version 20081201.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(**************************************************************************)
 
2
(*                                                                        *)
 
3
(*  This file is part of Frama-C.                                         *)
 
4
(*                                                                        *)
 
5
(*  Copyright (C) 2007-2008                                               *)
 
6
(*    CEA   (Commissariat � l'�nergie Atomique)                           *)
 
7
(*    INRIA (Institut National de Recherche en Informatique et en         *)
 
8
(*           Automatique)                                                 *)
 
9
(*                                                                        *)
 
10
(*  you can redistribute it and/or modify it under the terms of the GNU   *)
 
11
(*  Lesser General Public License as published by the Free Software       *)
 
12
(*  Foundation, version 2.1.                                              *)
 
13
(*                                                                        *)
 
14
(*  It is distributed in the hope that it will be useful,                 *)
 
15
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
 
16
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
 
17
(*  GNU Lesser General Public License for more details.                   *)
 
18
(*                                                                        *)
 
19
(*  See the GNU Lesser General Public License version v2.1                *)
 
20
(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
 
21
(*                                                                        *)
 
22
(**************************************************************************)
 
23
 
 
24
(** Slicing  module public macros that should be used to avoid  using the type
 
25
* concrete definition from other modules.
 
26
*)
 
27
 
 
28
(**/**)
 
29
 
 
30
open Cil_types
 
31
 
 
32
module T = SlicingTypes.Internals
 
33
 
 
34
exception Break
 
35
 
 
36
(**/**)
 
37
 
 
38
(** {2 Debug and utils} *)
 
39
 
 
40
let has_debug n = Debug.has_debug Cmdline.Slicing.Mode.Verbose.get n
 
41
let debug n format = Debug.debug_f (has_debug n) format
 
42
 
 
43
let cbug assert_cond msg = 
 
44
  if not assert_cond then raise (SlicingTypes.Slicing_Internal_Error msg)
 
45
 
 
46
let bug msg = raise (SlicingTypes.Slicing_Internal_Error msg)
 
47
 
 
48
let sprintf = Cil.fprintf_to_string
 
49
 
 
50
(** {2 Options} *)
 
51
 
 
52
let str_level_option opt = match opt with
 
53
  |  T.DontSlice -> "DontSlice"
 
54
  |  T.DontSliceButComputeMarks -> "DontSliceButComputeMarks"
 
55
  |  T.MinNbSlice -> "MinNbSlice"
 
56
  |  T.MaxNbSlice -> "MaxNbSlice"
 
57
 
 
58
let translate_num_to_slicing_level n =
 
59
  match n with
 
60
      | 0 -> T.DontSlice
 
61
      | 1 -> T.DontSliceButComputeMarks
 
62
      | 2 -> T.MinNbSlice 
 
63
      | 3 -> T.MaxNbSlice
 
64
      | _ -> raise SlicingTypes.WrongSlicingLevel
 
65
 
 
66
let get_default_level_option defined_function =
 
67
  if defined_function || (Cmdline.Slicing.Mode.SliceUndef.get ()) then 
 
68
    translate_num_to_slicing_level (Cmdline.Slicing.Mode.Calls.get ())
 
69
  else T.DontSlice 
 
70
 
 
71
let get_str_default_level_option defined_function = 
 
72
  str_level_option (get_default_level_option defined_function)
 
73
                     
 
74
(** {2 Getting [fct_info] and others } *)
 
75
 
 
76
let get_proj_appli proj = proj.T.application
 
77
 
 
78
(** {4 getting [svar]} *)
 
79
 
 
80
let fi_svar fi = Kernel_function.get_vi fi.T.fi_kf
 
81
 
 
82
let ff_svar ff = fi_svar (ff.T.ff_fct)
 
83
 
 
84
(** {4 getting [fct_info]} *)
 
85
 
 
86
(** Get the fct_info if it exists or build a new fct_info. *)
 
87
let get_kf_fi proj kf = 
 
88
  let fct_var = Kernel_function.get_vi kf in
 
89
  try
 
90
    let fi = Cilutil.VarinfoHashtbl.find proj.T.functions fct_var in fi
 
91
  with Not_found -> 
 
92
    let fi_def, is_def = 
 
93
      try let def = Kernel_function.get_definition kf in Some def, true
 
94
      with Kernel_function.No_Definition -> None, false
 
95
    in
 
96
    let new_fi = { 
 
97
      T.fi_kf = kf;
 
98
      T.fi_def = fi_def;
 
99
      T.fi_top = None;
 
100
      T.fi_level_option = get_default_level_option is_def;
 
101
      T.fi_init_marks = None ; 
 
102
      T.fi_slices = [] ; 
 
103
      T.fi_next_ff_num = 1; 
 
104
      T.f_called_by = [] }
 
105
    in
 
106
      Cilutil.VarinfoHashtbl.add proj.T.functions fct_var new_fi;
 
107
      new_fi
 
108
 
 
109
let fold_fi f acc proj = 
 
110
  Cilutil.VarinfoHashtbl.fold (fun _v fi acc -> f acc fi) proj.T.functions acc
 
111
 
 
112
let ff_fi ff = ff.T.ff_fct
 
113
 
 
114
let f_fi f = match f with
 
115
  | T.FctSrc fct -> fct
 
116
  | T.FctSliced ff -> ff_fi ff
 
117
 
 
118
(** {4 getting names} *)
 
119
 
 
120
let fi_name fi = let svar = fi_svar fi in svar.Cil_types.vname
 
121
 
 
122
(** get the name of the function corresponding to that slice. *)
 
123
let ff_name ff =
 
124
  let fi = ff_fi ff in
 
125
  let ff_id = ff.T.ff_id in
 
126
  let fct_name = fi_name fi in
 
127
    (fct_name ^ "_slice_" ^ (string_of_int (ff_id)))
 
128
 
 
129
let f_name f = match f with
 
130
  | T.FctSrc fct -> fi_name fct
 
131
  | T.FctSliced ff -> ff_name ff
 
132
 
 
133
let ff_src_name ff = fi_name (ff_fi ff)
 
134
 
 
135
let pdg_name pdg = 
 
136
  Kernel_function.get_name ( PdgTypes.Pdg.get_kf pdg)
 
137
 
 
138
(** {4 getting [kernel_function]} *)
 
139
 
 
140
let get_fi_kf fi = fi.T.fi_kf 
 
141
 
 
142
let get_ff_kf ff =  let fi = ff_fi ff in get_fi_kf fi
 
143
 
 
144
let get_pdg_kf pdg = PdgTypes.Pdg.get_kf pdg
 
145
 
 
146
(** {4 getting PDG} *)
 
147
 
 
148
let get_fi_pdg fi = let kf = get_fi_kf fi in  !Db.Pdg.get kf
 
149
 
 
150
let get_ff_pdg ff = get_fi_pdg (ff_fi ff)
 
151
 
 
152
(** {4 getting the slicing level} *)
 
153
 
 
154
 
 
155
let fi_slicing_level fi = fi.T.fi_level_option
 
156
 
 
157
let ff_slicing_level ff = fi_slicing_level (ff_fi ff)
 
158
 
 
159
let change_fi_slicing_level fi slicing_level =
 
160
    fi.T.fi_level_option <- slicing_level
 
161
 
 
162
(** @raise SlicingTypes.WrongSlicingLevel if [n] is not valid.
 
163
* *)
 
164
let change_slicing_level proj kf n =
 
165
  let slicing_level = translate_num_to_slicing_level n in
 
166
  let fi = get_kf_fi proj kf in (* build if if it doesn't exist *)
 
167
    change_fi_slicing_level fi slicing_level
 
168
 
 
169
(** {2 functions and slices} *)
 
170
 
 
171
let fi_slices fi = fi.T.fi_slices
 
172
 
 
173
(** {4 Comparisons} *)
 
174
 
 
175
let equal_fi fi1 fi2 = 
 
176
  let v1 = fi_svar fi1 in
 
177
  let v2 = fi_svar fi2 in
 
178
    v1.vid = v2.vid
 
179
 
 
180
let equal_ff ff1 ff2 = (equal_fi ff1.T.ff_fct ff2.T.ff_fct) && 
 
181
                       (ff1.T.ff_id = ff2.T.ff_id)
 
182
 
 
183
let equal_f f1 f2 =
 
184
  match f1, f2 with
 
185
    | T.FctSrc fi1, T.FctSrc fi2 -> equal_fi fi1 fi2
 
186
    | T.FctSliced ff1, T.FctSliced ff2 -> equal_ff ff1 ff2
 
187
    | _ -> false
 
188
  
 
189
 
 
190
(** {2 Calls} *)
 
191
 
 
192
let same_call c1 c2 = (c1.sid = c2.sid)
 
193
 
 
194
let same_ff_call (f1,c1) (f2,c2) =
 
195
  equal_ff f1 f2 && same_call c1 c2
 
196
 
 
197
let is_call_stmt stmt =
 
198
  match stmt.skind with Instr (Call _) -> true | _ -> false
 
199
 
 
200
let get_called_kf call_stmt =
 
201
  match call_stmt.skind with 
 
202
    | Instr (Call (_, funcexp,_,_)) ->
 
203
        let _funcexp_dpds, called_functions =
 
204
          !Db.Value.expr_to_kernel_function 
 
205
             ~with_alarms:CilE.warn_none_mode
 
206
            (Kstmt call_stmt) ~deps:(Some Locations.Zone.bottom) funcexp in
 
207
          (match called_functions with | kf :: [] -> kf
 
208
                                       | _ -> raise SlicingTypes.PtrCallExpr)
 
209
    | _ -> raise (Invalid_argument "Not a call statement !")
 
210
 
 
211
let is_variadic kf =
 
212
  let varf = Kernel_function.get_vi kf in
 
213
    match varf.vtype with
 
214
        TFun (_, _, is_variadic, _) -> is_variadic
 
215
      | _ -> (bug "The variable of a kernel_function has to be a function !")
 
216
 
 
217
(** get the [fct_info] of the called function, if we know it *)
 
218
let get_fi_call proj call =
 
219
  try
 
220
    let kf = get_called_kf call in
 
221
      if is_variadic kf then None
 
222
      else
 
223
        let fct_info = get_kf_fi proj kf in
 
224
          Some fct_info
 
225
  with SlicingTypes.PtrCallExpr -> None
 
226
 
 
227
let is_src_fun_called proj kf =
 
228
  let fi = get_kf_fi proj kf in
 
229
  match fi.T.f_called_by with [] -> false | _ -> true
 
230
 
 
231
let is_src_fun_visible proj kf =
 
232
  let is_fi_top fi = match fi.T.fi_top with None -> false | Some _ -> true 
 
233
  in is_src_fun_called proj kf || is_fi_top (get_kf_fi proj kf)
 
234
    
 
235
let get_calls_to_ff ff = ff.T.ff_called_by
 
236
 
 
237
let get_calls_to_src fi = fi.T.f_called_by
 
238
 
 
239
let fi_has_persistent_selection fi =
 
240
        (match fi.T.fi_init_marks with None -> false | _ -> true)
 
241
 
 
242
let has_persistent_selection proj kf =
 
243
  let fi = get_kf_fi proj kf in
 
244
    fi_has_persistent_selection fi
 
245
 
 
246
 
 
247
(*
 
248
Local Variables:
 
249
compile-command: "LC_ALL=C make -C ../.. -j"
 
250
End:
 
251
*)