diff --git a/Changelog b/Changelog index fdd6af530d7a908fe316ff318a6de3e8daf87ddf..fdeab1fa81a4f63f4457c77819a04b02671bb6a4 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,9 @@ Open Source Release <next-release> ################################## +o! Kernel [2019/08/02] Functions over visitor's behaviors have been moved + from Cil into a new module Visitor_behavior. Apply the migration + script potassium2calcium.sh to update your plug-ins automatically. o! Sparecode [2019/07/26] Removed from Db. Use proper Sparecode API instead. -! Kernel [2019/07/24] OCaml version greater than or equal to 4.05.0 required. - Kernel [2019/07/24] Improve placeholders handling in -cpp-command diff --git a/Makefile b/Makefile index 66a68df323552efd31deb99e5602b262207800c7..72f0a63b88a1e0a40be8e93f25d1a163cb87cfe6 100644 --- a/Makefile +++ b/Makefile @@ -520,6 +520,7 @@ KERNEL_CMO=\ src/kernel_services/ast_queries/cil_const.cmo \ src/kernel_services/ast_queries/logic_env.cmo \ src/kernel_services/ast_queries/logic_const.cmo \ + src/kernel_services/visitors/visitor_behavior.cmo \ src/kernel_services/ast_queries/cil.cmo \ src/kernel_internals/parsing/errorloc.cmo \ src/kernel_services/ast_printing/cil_printer.cmo \ diff --git a/bin/migration_scripts/potassium2calcium.sh b/bin/migration_scripts/potassium2calcium.sh index b927f2094eee56786f785f1bdd81bae323ab9dfe..73f36e65462cd9623e8db919ce109821d868c871 100755 --- a/bin/migration_scripts/potassium2calcium.sh +++ b/bin/migration_scripts/potassium2calcium.sh @@ -84,6 +84,26 @@ process_file () -e "s/Transitioning\.List\./List./g" \ -e "s/Transitioning\.Stack\./Stack./g" \ -e "s/Transitioning\.String\./String./g" \ + -e "s/Cil\.Eid/Cil_const\.Eid/g" \ + -e "s/Cil\.Sid/Cil_const\.Sid/g" \ + -e "s/Cil\.mkCompInfo/Cil_const\.mkCompInfo/g" \ + -e "s/Cil\.copyCompInfo/Cil_const\.copyCompInfo/g" \ + -e "s/Cil\.visitor_behavior/Visitor_behavior\.t/g" \ + -e "s/Cil\.inplace_visit/Visitor_behavior\.inplace/g" \ + -e "s/Cil\.copy_visit/Visitor_behavior\.copy/g" \ + -e "s/Cil\.refresh_visit/Visitor_behavior\.refresh/g" \ + -e "s/Cil\.is_fresh_behavior/Visitor_behavior\.is_fresh/g" \ + -e "s/Cil\.is_copy_behavior/Visitor_behavior\.is_copy/g" \ + -e "s/Cil\.reset_behavior_/Visitor_behavior\.Reset\./g" \ + -e "s/Cil\.get_original_/Visitor_behavior\.Get_orig\./g" \ + -e "s/Cil\.get_/Visitor_behavior\.Get\./g" \ + -e "s/Cil\.set_orig_/Visitor_behavior\.Set_orig\./g" \ + -e "s/Cil\.set_/Visitor_behavior\.Set\./g" \ + -e "s/Cil\.unset_orig_/Visitor_behavior\.Unset_orig\./g" \ + -e "s/Cil\.unset_/Visitor_behavior\.Unset\./g" \ + -e "s/Cil\.memo_/Visitor_behavior\.Memo\./g" \ + -e "s/Cil\.iter_visitor_/Visitor_behavior\.Iter\./g" \ + -e "s/Cil\.fold_visitor_/Visitor_behavior\.Fold\./g" \ $file } diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 08eb5d8ee17919e849c7b5888e070d46e69029a5..2d3abcb762ac7e9a419a2be8c515b764ab150861 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -586,6 +586,8 @@ src/kernel_services/visitors/cabsvisit.ml: CIL src/kernel_services/visitors/cabsvisit.mli: CIL src/kernel_services/visitors/visitor.ml: CEA_LGPL src/kernel_services/visitors/visitor.mli: CEA_LGPL +src/kernel_services/visitors/visitor_behavior.ml: CEA_INRIA_LGPL +src/kernel_services/visitors/visitor_behavior.mli: CEA_INRIA_LGPL src/libraries/README.md: .ignore src/libraries/datatype/README.md: .ignore src/libraries/datatype/datatype.ml: CEA_LGPL diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index cd3d07b4f50795b3aff774f4ed95c472a900abf0..1b595764bf03ef02f94a6901f87658e97ab5b21d 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -1222,7 +1222,9 @@ let createCompInfo (iss: bool) (n: string) ~(norig: string) : compinfo * bool = H.find compInfoNameEnv key, false (* Only if not already in *) with Not_found -> begin (* Create a compinfo. This will have "cdefined" false. *) - let res = mkCompInfo iss n ~norig (fun _ ->[]) (fc_stdlib_attribute []) in + let res = + Cil_const.mkCompInfo iss n ~norig (fun _ ->[]) (fc_stdlib_attribute []) + in H.add compInfoNameEnv key res; res, true end @@ -9995,7 +9997,7 @@ and doStatement local_env (s : A.statement) : chunk = let copy_spec (old_f,new_f) formals_map spec = let obj = object - inherit Cil.genericCilVisitor (Cil.refresh_visit (Project.current())) + inherit Cil.genericCilVisitor (Visitor_behavior.refresh (Project.current())) method! vlogic_var_use lv = match lv.lv_origin with | None -> DoChildren diff --git a/src/kernel_internals/typing/cfg.ml b/src/kernel_internals/typing/cfg.ml index 2d52020ae408c3d0f22febebc4d5ce80263f006e..21e648adf5c318f6dd538eadb1f81ac982d868d4 100644 --- a/src/kernel_internals/typing/cfg.ml +++ b/src/kernel_internals/typing/cfg.ml @@ -127,7 +127,7 @@ let make_break_stmt loc env next = let rec cfgFun (fd : fundec) = nodeList := []; cfgBlock (init_env fd.sbody) fd.sbody None None None; - fd.smaxstmtid <- Some(Cil.Sid.next ()); + fd.smaxstmtid <- Some(Cil_const.Sid.next ()); fd.sallstmts <- List.rev !nodeList; nodeList := [] @@ -161,7 +161,7 @@ and cfgBlock env (blk: block) next break cont = (* Fill in the CFG info for a stmt Meaning of next, break, cont should be clear from earlier comment *) and cfgStmt env (s: stmt) next break cont = - if s.sid = -1 then s.sid <- Cil.Sid.next (); + if s.sid = -1 then s.sid <- Cil_const.Sid.next (); nodeList := s :: !nodeList; if s.succs <> [] then Kernel.fatal diff --git a/src/kernel_internals/typing/unroll_loops.ml b/src/kernel_internals/typing/unroll_loops.ml index c85d9b2aa7178af7dff2298349b53fb2639bff72..697409bca64ca11bc4872bc36262516489d8c9a3 100644 --- a/src/kernel_internals/typing/unroll_loops.ml +++ b/src/kernel_internals/typing/unroll_loops.ml @@ -318,7 +318,7 @@ let copy_block kf switch_label_action break_continue_must_change bl = labelled_stmt_tbl calls_tbl stmt = let result = { labels = []; - sid = Sid.next (); + sid = Cil_const.Sid.next (); succs = []; preds = []; skind = stmt.skind; @@ -627,14 +627,14 @@ class do_it global_find_init ((force:bool),(times:int)) = object(self) let break_label = fresh_label () in let break_lbl_stmt = mkEmptyStmt () in break_lbl_stmt.labels <- [break_label]; - break_lbl_stmt.sid <- Cil.Sid.next (); + break_lbl_stmt.sid <- Cil_const.Sid.next (); break_lbl_stmt in let mk_continue () = let continue_label = fresh_label () in let continue_lbl_stmt = mkEmptyStmt () in continue_lbl_stmt.labels <- [continue_label] ; - continue_lbl_stmt.sid <- Cil.Sid.next (); + continue_lbl_stmt.sid <- Cil_const.Sid.next (); continue_lbl_stmt in let current_continue = ref (mk_continue ()) in diff --git a/src/kernel_services/analysis/exn_flow.ml b/src/kernel_services/analysis/exn_flow.ml index ce65a50c9f099f06ec8bc4ac732d950928634387..8a1904e4b5bf025af481464ee7e0f8c0bc2c4ded 100644 --- a/src/kernel_services/analysis/exn_flow.ml +++ b/src/kernel_services/analysis/exn_flow.ml @@ -350,7 +350,8 @@ let generate_exn_union e exns = in let union_name = "__fc_exn_union" in let exn_kind_union = - Cil.mkCompInfo false union_name ~norig:union_name create_union_fields [] + Cil_const.mkCompInfo + false union_name ~norig:union_name create_union_fields [] in let create_struct_fields _ = let uncaught = (exn_uncaught_name, Cil.intType, None, [], loc) in @@ -363,7 +364,8 @@ let generate_exn_union e exns = in let struct_name = "__fc_exn_struct" in let exn_struct = - Cil.mkCompInfo true struct_name ~norig:struct_name create_struct_fields [] + Cil_const.mkCompInfo + true struct_name ~norig:struct_name create_struct_fields [] in exn_kind_union, exn_struct @@ -690,8 +692,10 @@ object(self) method private clean_catch_clause (bind,b as handler) acc = let remove_local v = - let f = Cil.get_fundec self#behavior (Extlib.the self#current_func) in - let v = Cil.get_varinfo self#behavior v in + let f = + Visitor_behavior.Get.fundec self#behavior (Extlib.the self#current_func) + in + let v = Visitor_behavior.Get.varinfo self#behavior v in f.slocals <- List.filter (fun v' -> v!=v') f.slocals; in match bind with diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index 0184c5caff71b00d91d7d5c9aa952a5d17c30bff..6b8f9d91e8e15bd13ef38dd1457acf7619bc17eb 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -210,12 +210,7 @@ let selfMachine_is_computed = TheMachine.is_computed let debugConstFold = false -(* TODO: migrate that to Cil_const as well *) -module Sid = State_builder.SharedCounter(struct let name = "sid" end) - -module Eid = State_builder.SharedCounter(struct let name = "eid" end) - -let new_exp ~loc e = { eloc = loc; eid = Eid.next (); enode = e } +let new_exp ~loc e = { eloc = loc; eid = Cil_const.Eid.next (); enode = e } let dummy_exp e = { eid = -1; enode = e; eloc = Cil_datatype.Location.unknown } @@ -291,7 +286,7 @@ let mkStmt ?(ghost=false) ?(valid_sid=false) ?(sattr=[]) (sk: stmtkind) : stmt = safely be used in tables. I only do it when performing Jessie analysis, as other plugins rely on specific sid values for their tests (e.g. slicing). *) - sid = if valid_sid then Sid.next () else -1; + sid = if valid_sid then Cil_const.Sid.next () else -1; succs = []; preds = []; ghost = ghost; sattr = sattr;} @@ -685,74 +680,12 @@ let is_empty_behavior b = b.b_assumes = [] && b.b_requires = [] && b.b_post_cond = [] && b.b_assigns = WritesAny && b.b_allocation = FreeAllocAny && b.b_extended = [] +let missingFieldName = "" (* "___missing_field_name"*) + (** Get the full name of a comp *) let compFullName comp = (if comp.cstruct then "struct " else "union ") ^ comp.cname - -let missingFieldName = "" (* "___missing_field_name"*) - -(* The next compindo identifier to use. Counts up. *) -let nextCompinfoKey = - let module M = - State_builder.SharedCounter(struct let name = "compinfokey" end) - in - M.next - -(** Creates a (potentially recursive) composite type. Make sure you add a - * GTag for it to the file! **) -let mkCompInfo - (isstruct: bool) - (n: string) - ?(norig=n) - (* fspec is a function that when given a forward - * representation of the structure type constructs the type of - * the fields. The function can ignore this argument if not - * constructing a recursive type. *) - (mkfspec: compinfo -> (string * typ * int option * attribute list * - location) list) - (a: attribute list) : compinfo = - - (* make a new name for anonymous structs *) - if n = "" then Kernel.fatal "mkCompInfo: missing structure name\n" ; - (* Make a new self cell and a forward reference *) - let comp = - { cstruct = isstruct; - corig_name = norig; - cname = n; - ckey = nextCompinfoKey (); - cfields = []; (* fields will be added afterwards. *) - cattr = a; - creferenced = false; - (* Make this compinfo undefined by default *) - cdefined = false; } - in - let flds = - List.map (fun (fn, ft, fb, fa, fl) -> - { fcomp = comp; - ftype = ft; - forig_name = fn; - fname = fn; - fbitfield = fb; - fattr = fa; - floc = fl; - faddrof = false; - fsize_in_bits = None; - foffset_in_bits = None; - fpadding_in_bits = None; - }) (mkfspec comp) in - comp.cfields <- flds; - if flds <> [] then comp.cdefined <- true; - comp - -(** Make a copy of a compinfo, changing the name and the key *) -let copyCompInfo ?(fresh=true) ci cname = - let ckey = if fresh then nextCompinfoKey () else ci.ckey in - let ci' = { ci with cname; ckey } in - (* Copy the fields and set the new pointers to parents *) - ci'.cfields <- List.map (fun f -> {f with fcomp = ci'}) ci'.cfields; - ci' - (** Different visiting actions. 'a will be instantiated with [exp], [instr], etc. @see Plugin Development Guide *) @@ -778,1046 +711,11 @@ type 'a visitAction = has changed and then apply the function on the node *) -type visitor_behavior = - { (* copy mutable structure which are not shared across the AST*) - cfile: file -> file; - cinitinfo: initinfo -> initinfo; - cblock: block -> block; - cfunspec: funspec -> funspec; - cfunbehavior: funbehavior -> funbehavior; - cidentified_term: identified_term -> identified_term; - cidentified_predicate: identified_predicate -> identified_predicate; - cexpr: exp -> exp; - ccode_annotation: code_annotation -> code_annotation; - (* get the copy of a shared value *) - get_stmt: stmt -> stmt; - get_compinfo: compinfo -> compinfo; - get_fieldinfo: fieldinfo -> fieldinfo; - get_model_info: model_info -> model_info; - get_enuminfo: enuminfo -> enuminfo; - get_enumitem: enumitem -> enumitem; - get_typeinfo: typeinfo -> typeinfo; - get_varinfo: varinfo -> varinfo; - get_logic_info: logic_info -> logic_info; - get_logic_type_info: logic_type_info -> logic_type_info; - get_logic_var: logic_var -> logic_var; - get_kernel_function: kernel_function -> kernel_function; - get_fundec: fundec -> fundec; - (* get the original value tied to a copy *) - get_original_stmt: stmt -> stmt; - get_original_compinfo: compinfo -> compinfo; - get_original_fieldinfo: fieldinfo -> fieldinfo; - get_original_model_info: model_info -> model_info; - get_original_enuminfo: enuminfo -> enuminfo; - get_original_enumitem: enumitem -> enumitem; - get_original_typeinfo: typeinfo -> typeinfo; - get_original_varinfo: varinfo -> varinfo; - get_original_logic_info: logic_info -> logic_info; - get_original_logic_type_info: logic_type_info -> logic_type_info; - get_original_logic_var: logic_var -> logic_var; - get_original_kernel_function: kernel_function -> kernel_function; - get_original_fundec: fundec -> fundec; - (* change a binding... use with care *) - set_stmt: stmt -> stmt -> unit; - set_compinfo: compinfo -> compinfo -> unit; - set_fieldinfo: fieldinfo -> fieldinfo -> unit; - set_model_info: model_info -> model_info -> unit; - set_enuminfo: enuminfo -> enuminfo -> unit; - set_enumitem: enumitem -> enumitem -> unit; - set_typeinfo: typeinfo -> typeinfo -> unit; - set_varinfo: varinfo -> varinfo -> unit; - set_logic_info: logic_info -> logic_info -> unit; - set_logic_type_info: logic_type_info -> logic_type_info -> unit; - set_logic_var: logic_var -> logic_var -> unit; - set_kernel_function: kernel_function -> kernel_function -> unit; - set_fundec: fundec -> fundec -> unit; - (* change a reference... use with care *) - set_orig_stmt: stmt -> stmt -> unit; - set_orig_compinfo: compinfo -> compinfo -> unit; - set_orig_fieldinfo: fieldinfo -> fieldinfo -> unit; - set_orig_model_info: model_info -> model_info -> unit; - set_orig_enuminfo: enuminfo -> enuminfo -> unit; - set_orig_enumitem: enumitem -> enumitem -> unit; - set_orig_typeinfo: typeinfo -> typeinfo -> unit; - set_orig_varinfo: varinfo -> varinfo -> unit; - set_orig_logic_info: logic_info -> logic_info -> unit; - set_orig_logic_type_info: logic_type_info -> logic_type_info -> unit; - set_orig_logic_var: logic_var -> logic_var -> unit; - set_orig_kernel_function: kernel_function -> kernel_function -> unit; - set_orig_fundec: fundec -> fundec -> unit; - - unset_varinfo: varinfo -> unit; - unset_compinfo: compinfo -> unit; - unset_enuminfo: enuminfo -> unit; - unset_enumitem: enumitem -> unit; - unset_typeinfo: typeinfo -> unit; - unset_stmt: stmt -> unit; - unset_logic_info: logic_info -> unit; - unset_logic_type_info: logic_type_info -> unit; - unset_fieldinfo: fieldinfo -> unit; - unset_model_info: model_info -> unit; - unset_logic_var: logic_var -> unit; - unset_kernel_function: kernel_function -> unit; - unset_fundec: fundec -> unit; - - unset_orig_varinfo: varinfo -> unit; - unset_orig_compinfo: compinfo -> unit; - unset_orig_enuminfo: enuminfo -> unit; - unset_orig_enumitem: enumitem -> unit; - unset_orig_typeinfo: typeinfo -> unit; - unset_orig_stmt: stmt -> unit; - unset_orig_logic_info: logic_info -> unit; - unset_orig_logic_type_info: logic_type_info -> unit; - unset_orig_fieldinfo: fieldinfo -> unit; - unset_orig_model_info: model_info -> unit; - unset_orig_logic_var: logic_var -> unit; - unset_orig_kernel_function: kernel_function -> unit; - unset_orig_fundec: fundec -> unit; - - (* copy fields that can referenced in other places of the AST*) - memo_stmt: stmt -> stmt; - memo_varinfo: varinfo -> varinfo; - memo_compinfo: compinfo -> compinfo; - memo_model_info: model_info -> model_info; - memo_enuminfo: enuminfo -> enuminfo; - memo_enumitem: enumitem -> enumitem; - memo_typeinfo: typeinfo -> typeinfo; - memo_logic_info: logic_info -> logic_info; - memo_logic_type_info: logic_type_info -> logic_type_info; - memo_fieldinfo: fieldinfo -> fieldinfo; - memo_logic_var: logic_var -> logic_var; - memo_kernel_function: kernel_function -> kernel_function; - memo_fundec: fundec -> fundec; - (* is the behavior a copy behavior *) - is_copy_behavior: bool; - is_fresh_behavior: bool; - project: Project.t option; - (* reset memoizing tables *) - reset_behavior_varinfo: unit -> unit; - reset_behavior_compinfo: unit -> unit; - reset_behavior_enuminfo: unit -> unit; - reset_behavior_enumitem: unit -> unit; - reset_behavior_typeinfo: unit -> unit; - reset_behavior_logic_info: unit -> unit; - reset_behavior_logic_type_info: unit -> unit; - reset_behavior_fieldinfo: unit -> unit; - reset_behavior_model_info: unit -> unit; - reset_behavior_stmt: unit -> unit; - reset_logic_var: unit -> unit; - reset_behavior_kernel_function: unit -> unit; - reset_behavior_fundec: unit -> unit; - (* iterates over tables *) - iter_visitor_varinfo: (varinfo -> varinfo -> unit) -> unit; - iter_visitor_compinfo: (compinfo -> compinfo -> unit) -> unit; - iter_visitor_enuminfo: (enuminfo -> enuminfo -> unit) -> unit; - iter_visitor_enumitem: (enumitem -> enumitem -> unit) -> unit; - iter_visitor_typeinfo: (typeinfo -> typeinfo -> unit) -> unit; - iter_visitor_stmt: (stmt -> stmt -> unit) -> unit; - iter_visitor_logic_info: (logic_info -> logic_info -> unit) -> unit; - iter_visitor_logic_type_info: - (logic_type_info -> logic_type_info -> unit) -> unit; - iter_visitor_fieldinfo: (fieldinfo -> fieldinfo -> unit) -> unit; - iter_visitor_model_info: (model_info -> model_info -> unit) -> unit; - iter_visitor_logic_var: (logic_var -> logic_var -> unit) -> unit; - iter_visitor_kernel_function: - (kernel_function -> kernel_function -> unit) -> unit; - iter_visitor_fundec: (fundec -> fundec -> unit) -> unit; - (* folds over tables *) - fold_visitor_varinfo: 'a.(varinfo -> varinfo -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_compinfo: 'a.(compinfo -> compinfo -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_enuminfo: 'a.(enuminfo -> enuminfo -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_enumitem: 'a.(enumitem -> enumitem -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_typeinfo: 'a.(typeinfo -> typeinfo -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_stmt: 'a.(stmt -> stmt -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_logic_info: - 'a. (logic_info -> logic_info -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_logic_type_info: - 'a.(logic_type_info -> logic_type_info -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_fieldinfo: - 'a.(fieldinfo -> fieldinfo -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_model_info: - 'a. (model_info -> model_info -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_logic_var: - 'a.(logic_var -> logic_var -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_kernel_function: - 'a.(kernel_function -> kernel_function -> 'a -> 'a) -> 'a -> 'a; - fold_visitor_fundec: - 'a.(fundec -> fundec -> 'a -> 'a) -> 'a -> 'a; - } - -let is_copy_behavior b = b.is_copy_behavior - -let is_fresh_behavior b = b.is_fresh_behavior - -let memo_varinfo b = b.memo_varinfo -let memo_compinfo b = b.memo_compinfo -let memo_fieldinfo b = b.memo_fieldinfo -let memo_model_info b = b.memo_model_info -let memo_enuminfo b = b.memo_enuminfo -let memo_enumitem b = b.memo_enumitem -let memo_stmt b = b.memo_stmt -let memo_typeinfo b = b.memo_typeinfo -let memo_logic_info b = b.memo_logic_info -let memo_logic_type_info b = b.memo_logic_type_info -let memo_logic_var b = b.memo_logic_var -let memo_kernel_function b = b.memo_kernel_function -let memo_fundec b = b.memo_fundec - -let reset_behavior_varinfo b = b.reset_behavior_varinfo () -let reset_behavior_compinfo b = b.reset_behavior_compinfo () -let reset_behavior_enuminfo b = b.reset_behavior_enuminfo () -let reset_behavior_enumitem b = b.reset_behavior_enumitem () -let reset_behavior_typeinfo b = b.reset_behavior_typeinfo () -let reset_behavior_logic_info b = b.reset_behavior_logic_info () -let reset_behavior_logic_type_info b = b.reset_behavior_logic_type_info () -let reset_behavior_fieldinfo b = b.reset_behavior_fieldinfo () -let reset_behavior_model_info b = b.reset_behavior_model_info () -let reset_behavior_stmt b = b.reset_behavior_stmt () -let reset_logic_var b = b.reset_logic_var () -let reset_behavior_kernel_function b = b.reset_behavior_kernel_function () -let reset_behavior_fundec b = b.reset_behavior_fundec () - -let get_varinfo b = b.get_varinfo -let get_compinfo b = b.get_compinfo -let get_fieldinfo b = b.get_fieldinfo -let get_model_info b = b.get_model_info -let get_enuminfo b = b.get_enuminfo -let get_enumitem b = b.get_enumitem -let get_stmt b = b.get_stmt -let get_typeinfo b = b.get_typeinfo -let get_logic_info b = b.get_logic_info -let get_logic_type_info b = b.get_logic_type_info -let get_logic_var b = b.get_logic_var -let get_kernel_function b = b.get_kernel_function -let get_fundec b = b.get_fundec - -let get_original_varinfo b = b.get_original_varinfo -let get_original_compinfo b = b.get_original_compinfo -let get_original_fieldinfo b = b.get_original_fieldinfo -let get_original_model_info b = b.get_original_model_info -let get_original_enuminfo b = b.get_original_enuminfo -let get_original_enumitem b = b.get_original_enumitem -let get_original_stmt b = b.get_original_stmt -let get_original_typeinfo b = b.get_original_typeinfo -let get_original_logic_info b = b.get_original_logic_info -let get_original_logic_type_info b = b.get_original_logic_type_info -let get_original_logic_var b = b.get_original_logic_var -let get_original_kernel_function b = b.get_original_kernel_function -let get_original_fundec b = b.get_original_fundec - -let set_varinfo b = b.set_varinfo -let set_compinfo b = b.set_compinfo -let set_fieldinfo b = b.set_fieldinfo -let set_model_info b = b.set_model_info -let set_enuminfo b = b.set_enuminfo -let set_enumitem b = b.set_enumitem -let set_stmt b = b.set_stmt -let set_typeinfo b = b.set_typeinfo -let set_logic_info b = b.set_logic_info -let set_logic_type_info b = b.set_logic_type_info -let set_logic_var b = b.set_logic_var -let set_kernel_function b = b.set_kernel_function -let set_fundec b = b.set_fundec - -let set_orig_varinfo b = b.set_orig_varinfo -let set_orig_compinfo b = b.set_orig_compinfo -let set_orig_fieldinfo b = b.set_orig_fieldinfo -let set_orig_model_info b = b.set_model_info -let set_orig_enuminfo b = b.set_orig_enuminfo -let set_orig_enumitem b = b.set_orig_enumitem -let set_orig_stmt b = b.set_orig_stmt -let set_orig_typeinfo b = b.set_orig_typeinfo -let set_orig_logic_info b = b.set_orig_logic_info -let set_orig_logic_type_info b = b.set_orig_logic_type_info -let set_orig_logic_var b = b.set_orig_logic_var -let set_orig_kernel_function b= b.set_orig_kernel_function -let set_orig_fundec b = b.set_orig_fundec - -let unset_varinfo b = b.unset_varinfo -let unset_compinfo b = b.unset_compinfo -let unset_fieldinfo b = b.unset_fieldinfo -let unset_model_info b = b.unset_model_info -let unset_enuminfo b = b.unset_enuminfo -let unset_enumitem b = b.unset_enumitem -let unset_stmt b = b.unset_stmt -let unset_typeinfo b = b.unset_typeinfo -let unset_logic_info b = b.unset_logic_info -let unset_logic_type_info b = b.unset_logic_type_info -let unset_logic_var b = b.unset_logic_var -let unset_kernel_function b = b.unset_kernel_function -let unset_fundec b = b.unset_fundec - -let unset_orig_varinfo b = b.unset_orig_varinfo -let unset_orig_compinfo b = b.unset_orig_compinfo -let unset_orig_fieldinfo b = b.unset_orig_fieldinfo -let unset_orig_model_info b = b.unset_model_info -let unset_orig_enuminfo b = b.unset_orig_enuminfo -let unset_orig_enumitem b = b.unset_orig_enumitem -let unset_orig_stmt b = b.unset_orig_stmt -let unset_orig_typeinfo b = b.unset_orig_typeinfo -let unset_orig_logic_info b = b.unset_orig_logic_info -let unset_orig_logic_type_info b = b.unset_orig_logic_type_info -let unset_orig_logic_var b = b.unset_orig_logic_var -let unset_orig_kernel_function b= b.unset_orig_kernel_function -let unset_orig_fundec b = b.unset_orig_fundec - -let iter_visitor_varinfo b = b.iter_visitor_varinfo -let iter_visitor_compinfo b = b.iter_visitor_compinfo -let iter_visitor_enuminfo b = b.iter_visitor_enuminfo -let iter_visitor_enumitem b = b.iter_visitor_enumitem -let iter_visitor_typeinfo b = b.iter_visitor_typeinfo -let iter_visitor_stmt b = b.iter_visitor_stmt -let iter_visitor_logic_info b= b.iter_visitor_logic_info -let iter_visitor_logic_type_info b = b .iter_visitor_logic_type_info -let iter_visitor_fieldinfo b = b.iter_visitor_fieldinfo -let iter_visitor_model_info b = b.iter_visitor_model_info -let iter_visitor_logic_var b = b.iter_visitor_logic_var -let iter_visitor_kernel_function b = b.iter_visitor_kernel_function -let iter_visitor_fundec b = b.iter_visitor_fundec - -let fold_visitor_varinfo b = b.fold_visitor_varinfo -let fold_visitor_compinfo b = b.fold_visitor_compinfo -let fold_visitor_enuminfo b = b.fold_visitor_enuminfo -let fold_visitor_enumitem b = b.fold_visitor_enumitem -let fold_visitor_typeinfo b = b.fold_visitor_typeinfo -let fold_visitor_stmt b = b.fold_visitor_stmt -let fold_visitor_logic_info b = b.fold_visitor_logic_info -let fold_visitor_logic_type_info b = b.fold_visitor_logic_type_info -let fold_visitor_fieldinfo b = b.fold_visitor_fieldinfo -let fold_visitor_model_info b = b.fold_visitor_model_info -let fold_visitor_logic_var b = b.fold_visitor_logic_var -let fold_visitor_kernel_function b = b.fold_visitor_kernel_function -let fold_visitor_fundec b = b.fold_visitor_fundec let id = Extlib.id -let alphabetaunit _ _ = () let alphabetabeta _ x = x let alphabetafalse _ _ = false -let unitunit: unit -> unit = id let alphatrue _ = true -let alphaunit _ = () - -let inplace_visit () = - { cfile = id; - get_compinfo = id; - get_fieldinfo = id; - get_model_info = id; - get_enuminfo = id; - get_enumitem = id; - get_typeinfo = id; - get_varinfo = id; - get_logic_var = id; - get_stmt = id; - get_logic_info = id; - get_logic_type_info = id; - get_kernel_function = id; - get_fundec = id; - get_original_compinfo = id; - get_original_fieldinfo = id; - get_original_model_info = id; - get_original_enuminfo = id; - get_original_enumitem = id; - get_original_typeinfo = id; - get_original_varinfo = id; - get_original_logic_var = id; - get_original_stmt = id; - get_original_logic_info = id; - get_original_logic_type_info = id; - get_original_kernel_function = id; - get_original_fundec = id; - cinitinfo = id; - cblock = id; - cfunspec = id; - cfunbehavior = id; - cidentified_term = id; - cidentified_predicate = id; - ccode_annotation = id; - cexpr = id; - is_copy_behavior = false; - is_fresh_behavior = false; - project = None; - memo_varinfo = id; - memo_compinfo = id; - memo_enuminfo = id; - memo_enumitem = id; - memo_typeinfo = id; - memo_logic_info = id; - memo_logic_type_info = id; - memo_stmt = id; - memo_fieldinfo = id; - memo_model_info = id; - memo_logic_var = id; - memo_kernel_function = id; - memo_fundec = id; - set_varinfo = alphabetaunit; - set_compinfo = alphabetaunit; - set_enuminfo = alphabetaunit; - set_enumitem = alphabetaunit; - set_typeinfo = alphabetaunit; - set_logic_info = alphabetaunit; - set_logic_type_info = alphabetaunit; - set_stmt = alphabetaunit; - set_fieldinfo = alphabetaunit; - set_model_info = alphabetaunit; - set_logic_var = alphabetaunit; - set_kernel_function = alphabetaunit; - set_fundec = alphabetaunit; - set_orig_varinfo = alphabetaunit; - set_orig_compinfo = alphabetaunit; - set_orig_enuminfo = alphabetaunit; - set_orig_enumitem = alphabetaunit; - set_orig_typeinfo = alphabetaunit; - set_orig_logic_info = alphabetaunit; - set_orig_logic_type_info = alphabetaunit; - set_orig_stmt = alphabetaunit; - set_orig_fieldinfo = alphabetaunit; - set_orig_model_info = alphabetaunit; - set_orig_logic_var = alphabetaunit; - set_orig_kernel_function = alphabetaunit; - set_orig_fundec = alphabetaunit; - unset_varinfo = alphaunit; - unset_compinfo = alphaunit; - unset_enuminfo = alphaunit; - unset_enumitem = alphaunit; - unset_typeinfo = alphaunit; - unset_logic_info = alphaunit; - unset_logic_type_info = alphaunit; - unset_stmt = alphaunit; - unset_fieldinfo = alphaunit; - unset_model_info = alphaunit; - unset_logic_var = alphaunit; - unset_kernel_function = alphaunit; - unset_fundec = alphaunit; - unset_orig_varinfo = alphaunit; - unset_orig_compinfo = alphaunit; - unset_orig_enuminfo = alphaunit; - unset_orig_enumitem = alphaunit; - unset_orig_typeinfo = alphaunit; - unset_orig_logic_info = alphaunit; - unset_orig_logic_type_info = alphaunit; - unset_orig_stmt = alphaunit; - unset_orig_fieldinfo = alphaunit; - unset_orig_model_info = alphaunit; - unset_orig_logic_var = alphaunit; - unset_orig_kernel_function = alphaunit; - unset_orig_fundec = alphaunit; - reset_behavior_varinfo = unitunit; - reset_behavior_compinfo = unitunit; - reset_behavior_enuminfo = unitunit; - reset_behavior_enumitem = unitunit; - reset_behavior_typeinfo = unitunit; - reset_behavior_logic_info = unitunit; - reset_behavior_logic_type_info = unitunit; - reset_behavior_fieldinfo = unitunit; - reset_behavior_model_info = unitunit; - reset_behavior_stmt = unitunit; - reset_logic_var = unitunit; - reset_behavior_kernel_function = unitunit; - reset_behavior_fundec = unitunit; - iter_visitor_varinfo = alphaunit; - iter_visitor_compinfo = alphaunit; - iter_visitor_enuminfo = alphaunit; - iter_visitor_enumitem = alphaunit; - iter_visitor_typeinfo = alphaunit; - iter_visitor_stmt = alphaunit; - iter_visitor_logic_info = alphaunit; - iter_visitor_logic_type_info = alphaunit; - iter_visitor_fieldinfo = alphaunit; - iter_visitor_model_info = alphaunit; - iter_visitor_logic_var = alphaunit; - iter_visitor_kernel_function = alphaunit; - iter_visitor_fundec = alphaunit; - fold_visitor_varinfo = alphabetabeta; - fold_visitor_compinfo = alphabetabeta; - fold_visitor_enuminfo = alphabetabeta; - fold_visitor_enumitem = alphabetabeta; - fold_visitor_typeinfo = alphabetabeta; - fold_visitor_stmt = alphabetabeta; - fold_visitor_logic_info = alphabetabeta; - fold_visitor_logic_type_info = alphabetabeta; - fold_visitor_fieldinfo = alphabetabeta; - fold_visitor_model_info = alphabetabeta; - fold_visitor_logic_var = alphabetabeta; - fold_visitor_kernel_function = alphabetabeta; - fold_visitor_fundec = alphabetabeta; - } - -let copy_visit_gen fresh prj = - let varinfos = Cil_datatype.Varinfo.Hashtbl.create 103 in - let compinfos = Cil_datatype.Compinfo.Hashtbl.create 17 in - let enuminfos = Cil_datatype.Enuminfo.Hashtbl.create 17 in - let enumitems = Cil_datatype.Enumitem.Hashtbl.create 17 in - let typeinfos = Cil_datatype.Typeinfo.Hashtbl.create 17 in - let logic_infos = Cil_datatype.Logic_info.Hashtbl.create 17 in - let logic_type_infos = Cil_datatype.Logic_type_info.Hashtbl.create 17 in - let fieldinfos = Cil_datatype.Fieldinfo.Hashtbl.create 17 in - let model_infos = Cil_datatype.Model_info.Hashtbl.create 17 in - let stmts = Cil_datatype.Stmt.Hashtbl.create 103 in - let logic_vars = Cil_datatype.Logic_var.Hashtbl.create 17 in - let kernel_functions = Cil_datatype.Kf.Hashtbl.create 17 in - let fundecs = Cil_datatype.Varinfo.Hashtbl.create 17 in - let orig_varinfos = Cil_datatype.Varinfo.Hashtbl.create 103 in - let orig_compinfos = Cil_datatype.Compinfo.Hashtbl.create 17 in - let orig_enuminfos = Cil_datatype.Enuminfo.Hashtbl.create 17 in - let orig_enumitems = Cil_datatype.Enumitem.Hashtbl.create 17 in - let orig_typeinfos = Cil_datatype.Typeinfo.Hashtbl.create 17 in - let orig_logic_infos = Cil_datatype.Logic_info.Hashtbl.create 17 in - let orig_logic_type_infos = Cil_datatype.Logic_type_info.Hashtbl.create 17 in - let orig_fieldinfos = Cil_datatype.Fieldinfo.Hashtbl.create 17 in - let orig_model_infos = Cil_datatype.Model_info.Hashtbl.create 17 in - let orig_stmts = Cil_datatype.Stmt.Hashtbl.create 103 in - let orig_logic_vars = Cil_datatype.Logic_var.Hashtbl.create 17 in - let orig_kernel_functions = Cil_datatype.Kf.Hashtbl.create 17 in - let orig_fundecs = Cil_datatype.Varinfo.Hashtbl.create 17 in - let temp_set_logic_var x new_x = - Cil_datatype.Logic_var.Hashtbl.add logic_vars x new_x - in - let temp_set_orig_logic_var new_x x = - Cil_datatype.Logic_var.Hashtbl.add orig_logic_vars new_x x - in - let temp_unset_logic_var x = - Cil_datatype.Logic_var.Hashtbl.remove logic_vars x - in - let temp_unset_orig_logic_var new_x = - Cil_datatype.Logic_var.Hashtbl.remove orig_logic_vars new_x - in - let temp_memo_logic_var x = - (* Format.printf "search for %s#%d@." x.lv_name x.lv_id;*) - let res = - try Cil_datatype.Logic_var.Hashtbl.find logic_vars x - with Not_found -> - (* Format.printf "Not found@.";*) - let id = if fresh then Cil_const.new_raw_id () else x.lv_id in - let new_x = { x with lv_id = id } in - temp_set_logic_var x new_x; temp_set_orig_logic_var new_x x; new_x - in - (* Format.printf "res is %s#%d@." res.lv_name res.lv_id;*) - res - in - let temp_set_varinfo x new_x = - Cil_datatype.Varinfo.Hashtbl.add varinfos x new_x; - match x.vlogic_var_assoc, new_x.vlogic_var_assoc with - | None, _ | _, None -> () - | Some lx, Some new_lx -> - Cil_datatype.Logic_var.Hashtbl.add logic_vars lx new_lx - in - let temp_set_orig_varinfo new_x x = - Cil_datatype.Varinfo.Hashtbl.add orig_varinfos new_x x; - match new_x.vlogic_var_assoc, x.vlogic_var_assoc with - | None, _ | _, None -> () - | Some new_lx, Some lx -> - Cil_datatype.Logic_var.Hashtbl.add orig_logic_vars new_lx lx - in - let temp_unset_varinfo x = - Cil_datatype.Varinfo.Hashtbl.remove varinfos x; - match x.vlogic_var_assoc with - | None -> () - | Some lx -> Cil_datatype.Logic_var.Hashtbl.remove logic_vars lx - in - let temp_unset_orig_varinfo new_x = - Cil_datatype.Varinfo.Hashtbl.remove orig_varinfos new_x; - match new_x.vlogic_var_assoc with - | None -> () - | Some new_lx -> - Cil_datatype.Logic_var.Hashtbl.remove orig_logic_vars new_lx - in - let temp_memo_varinfo x = - try Cil_datatype.Varinfo.Hashtbl.find varinfos x - with Not_found -> - let new_x = - if fresh then Cil_const.copy_with_new_vid x else begin - let new_x = { x with vid = x.vid } in - (match x.vlogic_var_assoc with - | None -> () - | Some lv -> - let new_lv = { lv with lv_origin = Some new_x } in - new_x.vlogic_var_assoc <- Some new_lv); - new_x - end - in - temp_set_varinfo x new_x; temp_set_orig_varinfo new_x x; new_x - in - let temp_set_fundec f new_f = - Cil_datatype.Varinfo.Hashtbl.add fundecs f.svar new_f - in - let temp_set_orig_fundec new_f f = - Cil_datatype.Varinfo.Hashtbl.add orig_fundecs new_f.svar f - in - let temp_unset_fundec f = - Cil_datatype.Varinfo.Hashtbl.remove fundecs f.svar - in - let temp_unset_orig_fundec new_f = - Cil_datatype.Varinfo.Hashtbl.remove orig_fundecs new_f.svar - in - let temp_memo_fundec f = - try Cil_datatype.Varinfo.Hashtbl.find fundecs f.svar - with Not_found -> - let v = temp_memo_varinfo f.svar in - let new_f = { f with svar = v } in - temp_set_fundec f new_f; temp_set_orig_fundec new_f f; new_f - in - let temp_set_kernel_function kf new_kf = - Cil_datatype.Kf.Hashtbl.replace kernel_functions kf new_kf; - match kf.fundec, new_kf.fundec with - | Declaration(_,vi,_,_), Declaration(_,new_vi,_,_) - | Declaration(_,vi,_,_), Definition({ svar = new_vi }, _) - | Definition({svar = vi},_), Declaration(_,new_vi,_,_) -> - temp_set_varinfo vi new_vi - | Definition (fundec,_), Definition(new_fundec,_) -> - temp_set_fundec fundec new_fundec - in - let temp_set_orig_kernel_function new_kf kf = - Cil_datatype.Kf.Hashtbl.replace orig_kernel_functions new_kf kf; - match new_kf.fundec, kf.fundec with - | Declaration(_,new_vi,_,_), Declaration(_,vi,_,_) - | Declaration(_,new_vi,_,_), Definition({ svar = vi }, _) - | Definition({svar = new_vi},_), Declaration(_,vi,_,_) -> - temp_set_orig_varinfo new_vi vi - | Definition (new_fundec,_), Definition(fundec,_) -> - temp_set_orig_fundec new_fundec fundec - in - let temp_unset_kernel_function kf = - Cil_datatype.Kf.Hashtbl.remove kernel_functions kf; - match kf.fundec with - | Declaration(_,vi,_,_) -> temp_unset_varinfo vi - | Definition (fundec,_) -> temp_unset_fundec fundec - in - let temp_unset_orig_kernel_function new_kf = - Cil_datatype.Kf.Hashtbl.remove orig_kernel_functions new_kf; - match new_kf.fundec with - | Declaration(_,new_vi,_,_) -> temp_unset_orig_varinfo new_vi - | Definition (new_fundec,_) -> temp_unset_orig_fundec new_fundec - in - let temp_memo_kernel_function kf = - try Cil_datatype.Kf.Hashtbl.find kernel_functions kf - with Not_found -> - let new_kf = - match kf.fundec with - | Declaration (spec,vi,prms,loc) -> - let new_vi = temp_memo_varinfo vi in - { kf with fundec = Declaration(spec,new_vi,prms,loc) } - | Definition(f,loc) -> - let new_f = temp_memo_fundec f in - { kf with fundec = Definition(new_f,loc) } - in - temp_set_kernel_function kf new_kf; - temp_set_orig_kernel_function new_kf kf; - new_kf - in - let temp_set_compinfo c new_c = - Cil_datatype.Compinfo.Hashtbl.add compinfos c new_c; - List.iter2 - (fun f new_f -> Cil_datatype.Fieldinfo.Hashtbl.add fieldinfos f new_f) - c.cfields new_c.cfields - in - let temp_set_orig_compinfo new_c c = - Cil_datatype.Compinfo.Hashtbl.add orig_compinfos new_c c; - List.iter2 - (fun new_f f -> - Cil_datatype.Fieldinfo.Hashtbl.add orig_fieldinfos new_f f) - new_c.cfields c.cfields - in - let temp_unset_compinfo c = - Cil_datatype.Compinfo.Hashtbl.remove compinfos c; - List.iter - (fun f -> Cil_datatype.Fieldinfo.Hashtbl.remove fieldinfos f) c.cfields - in - let temp_unset_orig_compinfo new_c = - Cil_datatype.Compinfo.Hashtbl.remove orig_compinfos new_c; - List.iter - (fun new_f -> - Cil_datatype.Fieldinfo.Hashtbl.remove orig_fieldinfos new_f) - new_c.cfields - in - let temp_memo_compinfo c = - try Cil_datatype.Compinfo.Hashtbl.find compinfos c - with Not_found -> - let new_c = - copyCompInfo ~fresh c c.cname - in - temp_set_compinfo c new_c; temp_set_orig_compinfo new_c c; new_c - in - { cfile = (fun x -> { x with fileName = x.fileName }); - get_compinfo = - (fun x -> - try Cil_datatype.Compinfo.Hashtbl.find compinfos x with Not_found -> x); - get_fieldinfo = - (fun x -> - try Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x - with Not_found -> x); - get_model_info = - (fun x -> - try Cil_datatype.Model_info.Hashtbl.find model_infos x - with Not_found -> x); - get_enuminfo = - (fun x -> - try Cil_datatype.Enuminfo.Hashtbl.find enuminfos x with Not_found -> x); - get_enumitem = - (fun x -> - try Cil_datatype.Enumitem.Hashtbl.find enumitems x with Not_found -> x); - get_typeinfo = - (fun x -> - try Cil_datatype.Typeinfo.Hashtbl.find typeinfos x with Not_found -> x); - get_varinfo = - (fun x -> - try Cil_datatype.Varinfo.Hashtbl.find varinfos x with Not_found -> x); - get_stmt = - (fun x -> try Cil_datatype.Stmt.Hashtbl.find stmts x with Not_found -> x); - get_logic_info = - (fun x -> - try Cil_datatype.Logic_info.Hashtbl.find logic_infos x - with Not_found -> x); - get_logic_type_info = - (fun x -> - try Cil_datatype.Logic_type_info.Hashtbl.find logic_type_infos x - with Not_found -> x); - get_logic_var = - (fun x -> - try Cil_datatype.Logic_var.Hashtbl.find logic_vars x - with Not_found -> x); - get_kernel_function = - (fun x -> - try Cil_datatype.Kf.Hashtbl.find kernel_functions x - with Not_found -> x); - get_fundec = - (fun x -> - try Cil_datatype.Varinfo.Hashtbl.find fundecs x.svar - with Not_found -> x); - get_original_compinfo = - (fun x -> - try Cil_datatype.Compinfo.Hashtbl.find orig_compinfos x - with Not_found -> x); - get_original_fieldinfo = - (fun x -> - try Cil_datatype.Fieldinfo.Hashtbl.find orig_fieldinfos x - with Not_found -> x); - get_original_model_info = - (fun x -> - try Cil_datatype.Model_info.Hashtbl.find orig_model_infos x - with Not_found -> x); - get_original_enuminfo = - (fun x -> - try Cil_datatype.Enuminfo.Hashtbl.find orig_enuminfos x - with Not_found -> x); - get_original_enumitem = - (fun x -> - try Cil_datatype.Enumitem.Hashtbl.find orig_enumitems x - with Not_found -> x); - get_original_typeinfo = - (fun x -> - try Cil_datatype.Typeinfo.Hashtbl.find orig_typeinfos x - with Not_found -> x); - get_original_varinfo = - (fun x -> - try Cil_datatype.Varinfo.Hashtbl.find orig_varinfos x - with Not_found -> x); - get_original_stmt = - (fun x -> - try Cil_datatype.Stmt.Hashtbl.find orig_stmts x with Not_found -> x); - get_original_logic_var = - (fun x -> - try Cil_datatype.Logic_var.Hashtbl.find orig_logic_vars x - with Not_found -> x); - get_original_logic_info = - (fun x -> - try Cil_datatype.Logic_info.Hashtbl.find orig_logic_infos x - with Not_found -> x); - get_original_logic_type_info = - (fun x -> - try Cil_datatype.Logic_type_info.Hashtbl.find orig_logic_type_infos x - with Not_found -> x); - get_original_kernel_function = - (fun x -> - try Cil_datatype.Kf.Hashtbl.find orig_kernel_functions x - with Not_found -> x); - get_original_fundec = - (fun x -> - try Cil_datatype.Varinfo.Hashtbl.find orig_fundecs x.svar - with Not_found -> x); - cinitinfo = (fun x -> { init = x.init }); - cblock = (fun x -> { x with battrs = x.battrs }); - cfunspec = (fun x -> { x with spec_behavior = x.spec_behavior}); - cfunbehavior = (fun x -> { x with b_name = x.b_name}); - ccode_annotation = - if fresh then Logic_const.refresh_code_annotation - else (fun x -> { x with annot_id = x.annot_id }); - cidentified_predicate = - if fresh then Logic_const.refresh_predicate - else (fun x -> { x with ip_id = x.ip_id }); - cidentified_term = - if fresh then Logic_const.refresh_identified_term - else (fun x -> { x with it_id = x.it_id}); - cexpr = - (fun x -> - let id = if fresh then Eid.next () else x.eid in { x with eid = id }); - is_copy_behavior = true; - is_fresh_behavior = fresh; - project = Some prj; - reset_behavior_varinfo = - (fun () -> - Cil_datatype.Varinfo.Hashtbl.clear varinfos; - Cil_datatype.Varinfo.Hashtbl.clear orig_varinfos); - reset_behavior_compinfo = - (fun () -> - Cil_datatype.Compinfo.Hashtbl.clear compinfos; - Cil_datatype.Compinfo.Hashtbl.clear orig_compinfos); - reset_behavior_enuminfo = - (fun () -> - Cil_datatype.Enuminfo.Hashtbl.clear enuminfos; - Cil_datatype.Enuminfo.Hashtbl.clear orig_enuminfos); - reset_behavior_enumitem = - (fun () -> - Cil_datatype.Enumitem.Hashtbl.clear enumitems; - Cil_datatype.Enumitem.Hashtbl.clear orig_enumitems); - reset_behavior_typeinfo = - (fun () -> - Cil_datatype.Typeinfo.Hashtbl.clear typeinfos; - Cil_datatype.Typeinfo.Hashtbl.clear orig_typeinfos); - reset_behavior_logic_info = - (fun () -> - Cil_datatype.Logic_info.Hashtbl.clear logic_infos; - Cil_datatype.Logic_info.Hashtbl.clear orig_logic_infos); - reset_behavior_logic_type_info = - (fun () -> - Cil_datatype.Logic_type_info.Hashtbl.clear logic_type_infos; - Cil_datatype.Logic_type_info.Hashtbl.clear orig_logic_type_infos); - reset_behavior_fieldinfo = - (fun () -> - Cil_datatype.Fieldinfo.Hashtbl.clear fieldinfos; - Cil_datatype.Fieldinfo.Hashtbl.clear orig_fieldinfos); - reset_behavior_model_info = - (fun () -> - Cil_datatype.Model_info.Hashtbl.clear model_infos; - Cil_datatype.Model_info.Hashtbl.clear orig_model_infos); - reset_behavior_stmt = - (fun () -> - Cil_datatype.Stmt.Hashtbl.clear stmts; - Cil_datatype.Stmt.Hashtbl.clear orig_stmts); - reset_logic_var = - (fun () -> - Cil_datatype.Logic_var.Hashtbl.clear logic_vars; - Cil_datatype.Logic_var.Hashtbl.clear orig_logic_vars); - reset_behavior_kernel_function = - (fun () -> - Cil_datatype.Kf.Hashtbl.clear kernel_functions; - Cil_datatype.Kf.Hashtbl.clear orig_kernel_functions); - reset_behavior_fundec = - (fun () -> - Cil_datatype.Varinfo.Hashtbl.clear fundecs; - Cil_datatype.Varinfo.Hashtbl.clear orig_fundecs); - memo_varinfo = temp_memo_varinfo; - memo_compinfo = temp_memo_compinfo; - memo_enuminfo = - (fun x -> - try Cil_datatype.Enuminfo.Hashtbl.find enuminfos x - with Not_found -> - let new_x = { x with ename = x.ename } in - Cil_datatype.Enuminfo.Hashtbl.add enuminfos x new_x; - Cil_datatype.Enuminfo.Hashtbl.add orig_enuminfos new_x x; - new_x); - memo_enumitem = - (fun x -> - try Cil_datatype.Enumitem.Hashtbl.find enumitems x - with Not_found -> - let new_x = { x with einame = x.einame } in - Cil_datatype.Enumitem.Hashtbl.add enumitems x new_x; - Cil_datatype.Enumitem.Hashtbl.add orig_enumitems new_x x; - new_x); - memo_typeinfo = - (fun x -> - try Cil_datatype.Typeinfo.Hashtbl.find typeinfos x - with Not_found -> - let new_x = { x with tname = x.tname } in - Cil_datatype.Typeinfo.Hashtbl.add typeinfos x new_x; - Cil_datatype.Typeinfo.Hashtbl.add orig_typeinfos new_x x; - new_x); - memo_logic_info = - (fun x -> - try Cil_datatype.Logic_info.Hashtbl.find logic_infos x - with Not_found -> - let new_v = temp_memo_logic_var x.l_var_info in - let new_x = { x with l_var_info = new_v } in - Cil_datatype.Logic_info.Hashtbl.add logic_infos x new_x; - Cil_datatype.Logic_info.Hashtbl.add orig_logic_infos new_x x; - new_x); - memo_logic_type_info = - (fun x -> - try Cil_datatype.Logic_type_info.Hashtbl.find logic_type_infos x - with Not_found -> - let new_x = { x with lt_name = x.lt_name } in - Cil_datatype.Logic_type_info.Hashtbl.add logic_type_infos x new_x; - Cil_datatype.Logic_type_info.Hashtbl.add - orig_logic_type_infos new_x x; - new_x); - memo_stmt = - (fun x -> - try Cil_datatype.Stmt.Hashtbl.find stmts x - with Not_found -> - let sid = if fresh then Sid.next () else x.sid in - let new_x = { x with sid = sid } in - Cil_datatype.Stmt.Hashtbl.add stmts x new_x; - Cil_datatype.Stmt.Hashtbl.add orig_stmts new_x x; - new_x); - memo_fieldinfo = - (fun x -> - try Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x - with Not_found -> - let _ = temp_memo_compinfo x.fcomp in - (* memo_compinfo fills the field correspondence table as well *) - let new_x = Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x in - Cil_datatype.Fieldinfo.Hashtbl.add fieldinfos x new_x; - Cil_datatype.Fieldinfo.Hashtbl.add orig_fieldinfos new_x x; - new_x); - memo_model_info = - (fun x -> - try Cil_datatype.Model_info.Hashtbl.find model_infos x - with Not_found -> - let new_x = { x with mi_name = x.mi_name } in - Cil_datatype.Model_info.Hashtbl.add model_infos x new_x; - Cil_datatype.Model_info.Hashtbl.add orig_model_infos new_x x; - new_x - ); - memo_logic_var = temp_memo_logic_var; - memo_kernel_function = temp_memo_kernel_function; - memo_fundec = temp_memo_fundec; - set_varinfo = temp_set_varinfo; - set_compinfo = temp_set_compinfo; - set_enuminfo = Cil_datatype.Enuminfo.Hashtbl.replace enuminfos; - set_enumitem = Cil_datatype.Enumitem.Hashtbl.replace enumitems; - set_typeinfo = Cil_datatype.Typeinfo.Hashtbl.replace typeinfos; - set_logic_info = Cil_datatype.Logic_info.Hashtbl.replace logic_infos; - set_logic_type_info = - Cil_datatype.Logic_type_info.Hashtbl.replace logic_type_infos; - set_stmt = Cil_datatype.Stmt.Hashtbl.replace stmts; - set_fieldinfo = Cil_datatype.Fieldinfo.Hashtbl.replace fieldinfos; - set_model_info = Cil_datatype.Model_info.Hashtbl.replace model_infos; - set_logic_var = temp_set_logic_var; - set_kernel_function = temp_set_kernel_function; - set_fundec = temp_set_fundec; - set_orig_varinfo = temp_set_orig_varinfo; - set_orig_compinfo = temp_set_orig_compinfo; - set_orig_enuminfo = Cil_datatype.Enuminfo.Hashtbl.replace orig_enuminfos; - set_orig_enumitem = Cil_datatype.Enumitem.Hashtbl.replace orig_enumitems; - set_orig_typeinfo = Cil_datatype.Typeinfo.Hashtbl.replace orig_typeinfos; - set_orig_logic_info = - Cil_datatype.Logic_info.Hashtbl.replace orig_logic_infos; - set_orig_logic_type_info = - Cil_datatype.Logic_type_info.Hashtbl.replace orig_logic_type_infos; - set_orig_stmt = Cil_datatype.Stmt.Hashtbl.replace orig_stmts; - set_orig_fieldinfo = - Cil_datatype.Fieldinfo.Hashtbl.replace orig_fieldinfos; - set_orig_model_info = - Cil_datatype.Model_info.Hashtbl.replace orig_model_infos; - set_orig_logic_var = temp_set_orig_logic_var; - set_orig_kernel_function = temp_set_orig_kernel_function; - set_orig_fundec = temp_set_orig_fundec; - - unset_varinfo = temp_unset_varinfo; - unset_compinfo = temp_unset_compinfo; - unset_enuminfo = Cil_datatype.Enuminfo.Hashtbl.remove enuminfos; - unset_enumitem = Cil_datatype.Enumitem.Hashtbl.remove enumitems; - unset_typeinfo = Cil_datatype.Typeinfo.Hashtbl.remove typeinfos; - unset_logic_info = Cil_datatype.Logic_info.Hashtbl.remove logic_infos; - unset_logic_type_info = - Cil_datatype.Logic_type_info.Hashtbl.remove logic_type_infos; - unset_stmt = Cil_datatype.Stmt.Hashtbl.remove stmts; - unset_fieldinfo = Cil_datatype.Fieldinfo.Hashtbl.remove fieldinfos; - unset_model_info = Cil_datatype.Model_info.Hashtbl.remove model_infos; - unset_logic_var = temp_unset_logic_var; - unset_kernel_function = temp_unset_kernel_function; - unset_fundec = temp_unset_fundec; - - unset_orig_varinfo = temp_unset_orig_varinfo; - unset_orig_compinfo = temp_unset_orig_compinfo; - unset_orig_enuminfo = Cil_datatype.Enuminfo.Hashtbl.remove orig_enuminfos; - unset_orig_enumitem = Cil_datatype.Enumitem.Hashtbl.remove orig_enumitems; - unset_orig_typeinfo = Cil_datatype.Typeinfo.Hashtbl.remove orig_typeinfos; - unset_orig_logic_info = - Cil_datatype.Logic_info.Hashtbl.remove orig_logic_infos; - unset_orig_logic_type_info = - Cil_datatype.Logic_type_info.Hashtbl.remove orig_logic_type_infos; - unset_orig_stmt = Cil_datatype.Stmt.Hashtbl.remove orig_stmts; - unset_orig_fieldinfo = - Cil_datatype.Fieldinfo.Hashtbl.remove orig_fieldinfos; - unset_orig_model_info = - Cil_datatype.Model_info.Hashtbl.remove orig_model_infos; - unset_orig_logic_var = temp_unset_orig_logic_var; - unset_orig_kernel_function = temp_unset_orig_kernel_function; - unset_orig_fundec = temp_unset_orig_fundec; - - iter_visitor_varinfo = - (fun f -> Cil_datatype.Varinfo.Hashtbl.iter f varinfos); - iter_visitor_compinfo = - (fun f -> Cil_datatype.Compinfo.Hashtbl.iter f compinfos); - iter_visitor_enuminfo = - (fun f -> Cil_datatype.Enuminfo.Hashtbl.iter f enuminfos); - iter_visitor_enumitem = - (fun f -> Cil_datatype.Enumitem.Hashtbl.iter f enumitems); - iter_visitor_typeinfo = - (fun f -> Cil_datatype.Typeinfo.Hashtbl.iter f typeinfos); - iter_visitor_stmt = - (fun f -> Cil_datatype.Stmt.Hashtbl.iter f stmts); - iter_visitor_logic_info = - (fun f -> Cil_datatype.Logic_info.Hashtbl.iter f logic_infos); - iter_visitor_logic_type_info = - (fun f -> Cil_datatype.Logic_type_info.Hashtbl.iter f logic_type_infos); - iter_visitor_fieldinfo = - (fun f -> Cil_datatype.Fieldinfo.Hashtbl.iter f fieldinfos); - iter_visitor_model_info = - (fun f -> Cil_datatype.Model_info.Hashtbl.iter f model_infos); - iter_visitor_logic_var = - (fun f -> Cil_datatype.Logic_var.Hashtbl.iter f logic_vars); - iter_visitor_kernel_function = - (fun f -> Cil_datatype.Kf.Hashtbl.iter f kernel_functions); - iter_visitor_fundec = - (fun f -> - let f _ new_fundec = - let old_fundec = - Cil_datatype.Varinfo.Hashtbl.find orig_fundecs new_fundec.svar - in - f old_fundec new_fundec - in - Cil_datatype.Varinfo.Hashtbl.iter f fundecs); - fold_visitor_varinfo = - (fun f i -> Cil_datatype.Varinfo.Hashtbl.fold f varinfos i); - fold_visitor_compinfo = - (fun f i -> Cil_datatype.Compinfo.Hashtbl.fold f compinfos i); - fold_visitor_enuminfo = - (fun f i -> Cil_datatype.Enuminfo.Hashtbl.fold f enuminfos i); - fold_visitor_enumitem = - (fun f i -> Cil_datatype.Enumitem.Hashtbl.fold f enumitems i); - fold_visitor_typeinfo = - (fun f i -> Cil_datatype.Typeinfo.Hashtbl.fold f typeinfos i); - fold_visitor_stmt = - (fun f i -> Cil_datatype.Stmt.Hashtbl.fold f stmts i); - fold_visitor_logic_info = - (fun f i -> Cil_datatype.Logic_info.Hashtbl.fold f logic_infos i); - fold_visitor_logic_type_info = - (fun f i -> - Cil_datatype.Logic_type_info.Hashtbl.fold f logic_type_infos i); - fold_visitor_fieldinfo = - (fun f i -> Cil_datatype.Fieldinfo.Hashtbl.fold f fieldinfos i); - fold_visitor_model_info = - (fun f i -> Cil_datatype.Model_info.Hashtbl.fold f model_infos i); - fold_visitor_logic_var = - (fun f i -> Cil_datatype.Logic_var.Hashtbl.fold f logic_vars i); - fold_visitor_kernel_function = - (fun f i -> - Cil_datatype.Kf.Hashtbl.fold f kernel_functions i); - fold_visitor_fundec = - (fun f i -> - let f _ new_fundec acc = - let old_fundec = - Cil_datatype.Varinfo.Hashtbl.find orig_fundecs new_fundec.svar - in - f old_fundec new_fundec acc - in - Cil_datatype.Varinfo.Hashtbl.fold f fundecs i); - } - -let copy_visit = copy_visit_gen false - -let refresh_visit = copy_visit_gen true let visitor_tbl = Hashtbl.create 5 @@ -1831,8 +729,7 @@ let register_behavior_extension name ext = Hashtbl.add visitor_tbl name ext (** A visitor interface for traversing CIL trees. Create instantiations of * this type by specializing the class {!Cil.nopCilVisitor}. *) class type cilVisitor = object - - method behavior: visitor_behavior + method behavior: Visitor_behavior.t method project: Project.t option @@ -2013,7 +910,7 @@ class internal_genericCilVisitor current_func behavior queue: cilVisitor = object(self) method behavior = behavior - method project = behavior.project; + method project = Visitor_behavior.get_project behavior method plain_copy_visitor = let obj = @@ -2149,7 +1046,7 @@ class genericCilVisitor bhv = internal_genericCilVisitor current_func bhv queue class nopCilVisitor = object - inherit genericCilVisitor (inplace_visit ()) + inherit genericCilVisitor (Visitor_behavior.inplace ()) end let apply_on_project ?selection vis f arg = @@ -2371,14 +1268,14 @@ let debugVisit = false let visitCilConst vis c = match c with | CEnum ei -> (* In case of deep copy, we must change the enumitem*) - let ei' = vis#behavior.get_enumitem ei in + let ei' = Visitor_behavior.Get.enumitem vis#behavior ei in if ei' != ei then CEnum ei' else c | _ -> c let visitCilLConst vis c = match c with | LEnum ei -> (* In case of deep copy, we must change the enumitem*) - let ei' = vis#behavior.get_enumitem ei in + let ei' = Visitor_behavior.Get.enumitem vis#behavior ei in if ei' != ei then LEnum ei' else c | _ -> c @@ -2531,12 +1428,12 @@ and childrenTermNode vis tn = and visitCilLogicLabel vis l = doVisitCil vis - (copy_logic_label vis#behavior.is_copy_behavior) + (copy_logic_label (Visitor_behavior.is_copy vis#behavior)) vis#vlogic_label childrenLogicLabel l and childrenLogicLabel vis l = match l with - StmtLabel s -> s := vis#behavior.get_stmt !s; l + StmtLabel s -> s := Visitor_behavior.Get.stmt vis#behavior !s; l | FormalLabel _ | BuiltinLabel _ -> l and visitCilTermLval vis tl = @@ -2569,21 +1466,21 @@ and childrenTermOffset vis toff = TNoOffset -> toff | TField (fi, t) -> let t' = vOffset t in - let fi' = vis#behavior.get_fieldinfo fi in + let fi' = Visitor_behavior.Get.fieldinfo vis#behavior fi in if t' != t || fi != fi' then TField(fi',t') else toff | TIndex(t,o) -> let t' = vTerm t in let o' = vOffset o in if t' != t || o' != o then TIndex(t',o') else toff | TModel (mi,t) -> let t' = vOffset t in - let mi' = vis#behavior.get_model_info mi in + let mi' = Visitor_behavior.Get.model_info vis#behavior mi in if t' != t || mi != mi' then TModel(mi', t') else toff and visitCilLogicInfoUse vis li = (* First, visit the underlying varinfo to fill the copy tables if needed. *) let new_v = visitCilLogicVarUse vis li.l_var_info in let new_li = - doVisitCil vis vis#behavior.get_logic_info + doVisitCil vis (Visitor_behavior.Get.logic_info vis#behavior) vis#vlogic_info_use alphabetabeta li in new_li.l_var_info <- new_v; @@ -2596,7 +1493,7 @@ and visitCilLogicInfo vis li = let new_v = visitCilLogicVarDecl vis li.l_var_info in let res = doVisitCil - vis vis#behavior.memo_logic_info + vis (Visitor_behavior.Memo.logic_info vis#behavior) vis#vlogic_info_decl childrenLogicInfo li in res.l_var_info <- new_v; res @@ -2631,7 +1528,7 @@ and childrenLogicInfo vis li = li and visitCilLogicTypeInfo vis lt = - doVisitCil vis vis#behavior.memo_logic_type_info + doVisitCil vis (Visitor_behavior.Memo.logic_type_info vis#behavior) vis#vlogic_type_info_decl childrenLogicTypeInfo lt and childrenLogicTypeInfo vis lt = @@ -2652,7 +1549,7 @@ and childrenLogicTypeDef vis def = and visitCilLogicCtorInfoAddTable vis ctor = let ctor' = visitCilLogicCtorInfo vis ctor in - if is_copy_behavior vis#behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_logic_ctor ctor'.ctor_name ctor') @@ -2663,7 +1560,7 @@ and visitCilLogicCtorInfo vis ctor = doVisitCil vis id vis#vlogic_ctor_info_decl childrenLogicCtorInfo ctor and childrenLogicCtorInfo vis ctor = - let ctor_type = doVisitCil vis vis#behavior.get_logic_type_info + let ctor_type = doVisitCil vis (Visitor_behavior.Get.logic_type_info vis#behavior) vis#vlogic_type_info_use alphabetabeta ctor.ctor_type in let ctor_params = ctor.ctor_params in @@ -2682,7 +1579,7 @@ and childrenLogicType vis ty = if t != t' then Ctype t' else ty | Linteger | Lreal -> ty | Ltype (s,l) -> - let s' = doVisitCil vis vis#behavior.get_logic_type_info + let s' = doVisitCil vis (Visitor_behavior.Get.logic_type_info vis#behavior) vis#vlogic_type_info_use alphabetabeta s in let l' = mapNoCopy (visitCilLogicType vis) l in if s' != s || l' != l then Ltype (s',l') else ty @@ -2697,7 +1594,7 @@ and visitCilLogicVarDecl vis lv = (match lv.lv_origin with None -> () | Some cv -> lv.lv_name <- cv.vname); - doVisitCil vis vis#behavior.memo_logic_var vis#vlogic_var_decl + doVisitCil vis (Visitor_behavior.Memo.logic_var vis#behavior) vis#vlogic_var_decl childrenLogicVarDecl lv and childrenLogicVarDecl vis lv = @@ -2707,7 +1604,7 @@ and childrenLogicVarDecl vis lv = lv and visitCilLogicVarUse vis lv = - if vis#behavior.is_copy_behavior && + if Visitor_behavior.is_copy vis#behavior && (* In a copy visitor, there's always a project. Furthermore, if we target the current project, builtins are by definition already tied to logic_infos and should not be copied. @@ -2735,7 +1632,7 @@ and visitCilLogicVarUse vis lv = end) vis#get_filling_actions; end; - doVisitCil vis vis#behavior.get_logic_var vis#vlogic_var_use + doVisitCil vis (Visitor_behavior.Get.logic_var vis#behavior) vis#vlogic_var_use childrenLogicVarUse lv and childrenLogicVarUse vis lv = @@ -2748,7 +1645,7 @@ and visitCilQuantifiers vis lv = and visitCilIdPredicate vis ip = doVisitCil vis - vis#behavior.cidentified_predicate + (Visitor_behavior.cidentified_predicate vis#behavior) vis#videntified_predicate childrenIdentified_predicate ip @@ -2888,7 +1785,7 @@ and childrenPredicateNode vis p = if t' != t || n' != n || s1 != s1' || s2 != s2' then Pfresh (s1',s2',t',n') else p and visitCilIdTerm vis loc = - doVisitCil vis vis#behavior.cidentified_term vis#videntified_term + doVisitCil vis (Visitor_behavior.cidentified_term vis#behavior) vis#videntified_term childrenIdentified_term loc and childrenIdentified_term vis loc = let loc' = visitCilTerm vis loc.it_content in @@ -2937,7 +1834,7 @@ and childrenDeps vis d = if l !=l' then From l' else d and visitCilBehavior vis b = - doVisitCil vis vis#behavior.cfunbehavior + doVisitCil vis (Visitor_behavior.cfunbehavior vis#behavior) vis#vbehavior childrenBehavior b and childrenBehavior vis b = @@ -2959,7 +1856,7 @@ and visitCilExtended vis orig = with Not_found -> (fun _ _ -> DoChildren) in let e' = doVisitCil vis id (visit vis) childrenCilExtended orig.ext_kind in - if is_fresh_behavior vis#behavior then + if Visitor_behavior.is_fresh vis#behavior then Logic_const.new_acsl_extension orig.ext_name orig.ext_loc orig.ext_has_status e' else if orig.ext_kind == e' then orig else {orig with ext_kind = e'} @@ -2979,7 +1876,7 @@ and visitCilPredicates vis ps = mapNoCopy (visitCilIdPredicate vis) ps and visitCilBehaviors vis bs = mapNoCopy (visitCilBehavior vis) bs and visitCilFunspec vis s = - doVisitCil vis vis#behavior.cfunspec vis#vspec childrenSpec s + doVisitCil vis (Visitor_behavior.cfunspec vis#behavior) vis#vspec childrenSpec s and childrenSpec vis s = s.spec_behavior <- visitCilBehaviors vis s.spec_behavior; @@ -3042,13 +1939,13 @@ and visitCilModelInfo vis m = CurrentLoc.set m.mi_decl; let m' = doVisitCil - vis vis#behavior.memo_model_info vis#vmodel_info childrenModelInfo m + vis (Visitor_behavior.Memo.model_info vis#behavior) vis#vmodel_info childrenModelInfo m in CurrentLoc.set oldloc; if m' != m then begin (* reflect changes in the behavior tables for copy visitor. *) - vis#behavior.set_model_info m m'; - vis#behavior.set_orig_model_info m' m; + Visitor_behavior.Set.model_info vis#behavior m m'; + Visitor_behavior.Set_orig.model_info vis#behavior m' m; end; m' @@ -3063,7 +1960,7 @@ and childrenAnnotation vis a = match a with | Dfun_or_pred (li,loc) -> let li' = visitCilLogicInfo vis li in - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_logic_function_gen alphabetafalse li') @@ -3071,7 +1968,7 @@ and childrenAnnotation vis a = if li' != li then Dfun_or_pred (li',loc) else a | Dtype (ti,loc) -> let ti' = visitCilLogicTypeInfo vis ti in - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_logic_type ti'.lt_name ti') @@ -3085,21 +1982,21 @@ and childrenAnnotation vis a = else a | Dinvariant (p,loc) -> let p' = visitCilLogicInfo vis p in - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_logic_function_gen alphabetafalse p') vis#get_filling_actions; if p' != p then Dinvariant (p',loc) else a | Dtype_annot (ta,loc) -> let ta' = visitCilLogicInfo vis ta in - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_logic_function_gen alphabetafalse ta') vis#get_filling_actions; if ta' != ta then Dtype_annot (ta',loc) else a | Dmodel_annot (mfi,loc) -> let mfi' = visitCilModelInfo vis mfi in - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Queue.add (fun () -> Logic_env.add_model_field mfi') vis#get_filling_actions; if mfi' != mfi then Dmodel_annot (mfi',loc) else a @@ -3128,7 +2025,7 @@ and childrenAnnotation vis a = and visitCilCodeAnnotation vis ca = doVisitCil - vis vis#behavior.ccode_annotation vis#vcode_annot childrenCodeAnnot ca + vis (Visitor_behavior.ccode_annotation vis#behavior) vis#vcode_annot childrenCodeAnnot ca and childrenCodeAnnot vis ca = let vPred p = visitCilPredicate vis p in @@ -3173,7 +2070,7 @@ and childrenCodeAnnot vis ca = and visitCilExpr (vis: cilVisitor) (e: exp) : exp = let oldLoc = CurrentLoc.get () in CurrentLoc.set e.eloc; - let res = doVisitCil vis vis#behavior.cexpr vis#vexpr childrenExp e in + let res = doVisitCil vis (Visitor_behavior.cexpr vis#behavior) vis#vexpr childrenExp e in CurrentLoc.set oldLoc; res and childrenExp (vis: cilVisitor) (e: exp) : exp = @@ -3275,7 +2172,7 @@ and childrenOffset (vis: cilVisitor) (off: offset) : offset = match off with Field (f, o) -> let o' = vOff o in - let f' = vis#behavior.get_fieldinfo f in + let f' = Visitor_behavior.Get.fieldinfo vis#behavior f in if o' != o || f' != f then Field (f', o') else off | Index (e, o) -> let e' = visitCilExpr vis e in @@ -3356,8 +2253,8 @@ and childrenInstr (vis: cilVisitor) (i: instr) : instr = if e' != e then (id,s,e') else pair) asm_inputs_pre in let asm_gotos = - if vis#behavior.is_copy_behavior then - List.map (fun s -> ref (vis#behavior.memo_stmt !s)) ext.asm_gotos + if Visitor_behavior.is_copy vis#behavior then + List.map (fun s -> ref (Visitor_behavior.Memo.stmt vis#behavior !s)) ext.asm_gotos else ext.asm_gotos in if asm_outputs != asm_outputs_pre @@ -3381,7 +2278,7 @@ and visitCilStmt (vis:cilVisitor) (s: stmt) : stmt = let toPrepend : instr list ref = ref [] in (* childrenStmt may add to this *) let res = doVisitCil vis - vis#behavior.memo_stmt vis#vstmt (childrenStmt toPrepend) s in + (Visitor_behavior.Memo.stmt vis#behavior) vis#vstmt (childrenStmt toPrepend) s in let ghost = res.ghost in (* Now see if we have saved some instructions *) toPrepend := !toPrepend @ vis#unqueueInstr (); @@ -3425,9 +2322,9 @@ and childrenStmt (toPrepend: instr list ref) (vis:cilVisitor) (s:stmt): stmt = let writes' = mapNoCopy (visitCilLval vis) writes in let reads' = mapNoCopy (visitCilLval vis) reads in let calls' = - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then (* we need new references anyway, no need for mapNoCopy *) - List.map (fun x -> ref (vis#behavior.memo_stmt !x)) calls + List.map (fun x -> ref (Visitor_behavior.Memo.stmt vis#behavior !x)) calls else calls in if stmt' != stmt || writes' != writes || reads' != reads || @@ -3439,8 +2336,8 @@ and childrenStmt (toPrepend: instr list ref) (vis:cilVisitor) (s:stmt): stmt = in if seq' != seq then UnspecifiedSequence seq' else s.skind | Goto (sr,l) -> - if vis#behavior.is_copy_behavior then - Goto(ref (vis#behavior.memo_stmt !sr),l) + if Visitor_behavior.is_copy vis#behavior then + Goto(ref (Visitor_behavior.Memo.stmt vis#behavior !sr),l) else s.skind | Return (Some e, l) -> let e' = fExp e in @@ -3463,7 +2360,7 @@ and childrenStmt (toPrepend: instr list ref) (vis:cilVisitor) (s:stmt): stmt = let e' = fExp e in toPrepend := vis#unqueueInstr (); (* insert these before the switch *) let b' = fBlock b in - let stmts' = mapNoCopy (vis#behavior.get_stmt) stmts in + let stmts' = mapNoCopy (Visitor_behavior.Get.stmt vis#behavior) stmts in (* the stmts in b should have cleaned up after themselves.*) assertEmptyQueue vis; if e' != e || b' != b || stmts' != stmts then @@ -3545,8 +2442,8 @@ and visitCilCatch_binder vis cb = if v != v' || l != l' then Catch_exn(v',l') else cb | Catch_all -> cb and visitCilBlock (vis: cilVisitor) (b: block) : block = - let b' = vis#behavior.cblock b in - if vis#behavior.is_copy_behavior then begin + let b' = Visitor_behavior.cblock vis#behavior b in + if Visitor_behavior.is_copy vis#behavior then begin (* in case we are the main block of the current function, update immediately the sbody, so that makeLocalVar can be used seamlessly by the underlying visitor and associate the @@ -3554,7 +2451,7 @@ and visitCilBlock (vis: cilVisitor) (b: block) : block = *) match vis#current_func with | Some fd when fd.sbody == b -> - (get_fundec vis#behavior fd).sbody <- b' + (Visitor_behavior.Get.fundec vis#behavior fd).sbody <- b' | Some _ | None -> () end; doVisitCil vis id vis#vblock childrenBlock b' @@ -3564,8 +2461,8 @@ and childrenBlock (vis: cilVisitor) (b: block) : block = that wish to create a local into the innermost scope can simply append it to the current block. *) - let locals' = mapNoCopy (vis#behavior.get_varinfo) b.blocals in - let statics' = mapNoCopy (vis#behavior.get_varinfo) b.bstatics in + let locals' = mapNoCopy (Visitor_behavior.Get.varinfo vis#behavior) b.blocals in + let statics' = mapNoCopy (Visitor_behavior.Get.varinfo vis#behavior) b.bstatics in b.blocals <- locals'; b.bstatics <- statics'; let stmts' = mapNoCopy fStmt b.bstmts in @@ -3596,7 +2493,7 @@ and childrenType (vis : cilVisitor) (t : typ) : typ = (* DON'T recurse into the compinfo, this is done in visitCilGlobal. User can iterate over cinfo.cfields manually, if desired.*) | TComp(cinfo, _, a) -> - let cinfo' = vis#behavior.get_compinfo cinfo in + let cinfo' = Visitor_behavior.Get.compinfo vis#behavior cinfo in let a' = fAttr a in if a != a' || cinfo' != cinfo then TComp(cinfo',empty_size_cache (), a') else t @@ -3617,11 +2514,11 @@ and childrenType (vis : cilVisitor) (t : typ) : typ = | TNamed(t1, a) -> let a' = fAttr a in - let t1' = vis#behavior.get_typeinfo t1 in + let t1' = Visitor_behavior.Get.typeinfo vis#behavior t1 in if a' != a || t1' != t1 then TNamed (t1', a') else t | TEnum(enum,a) -> let a' = fAttr a in - let enum' = vis#behavior.get_enuminfo enum in + let enum' = Visitor_behavior.Get.enuminfo vis#behavior enum in if a' != a || enum' != enum then TEnum(enum',a') else t | TVoid _ | TInt _ | TFloat _ | TBuiltin_va_list _ -> (* no nested type. visit only the attributes. *) @@ -3635,7 +2532,7 @@ and visitCilVarDecl (vis : cilVisitor) (v : varinfo) : varinfo = let oldloc = CurrentLoc.get () in CurrentLoc.set v.vdecl; let res = - doVisitCil vis vis#behavior.memo_varinfo + doVisitCil vis (Visitor_behavior.Memo.varinfo vis#behavior) vis#vvdec childrenVarDecl v in CurrentLoc.set oldloc; res @@ -3643,7 +2540,7 @@ and childrenVarDecl (vis : cilVisitor) (v : varinfo) : varinfo = (* in case of refresh visitor, the associated new logic var has a different id. We must visit the original logic var associated to it. *) let visit_orig_var_assoc lv = - let o = vis#behavior.get_original_logic_var lv in + let o = Visitor_behavior.Get_orig.logic_var vis#behavior lv in visitCilLogicVarDecl vis o in v.vtype <- visitCilType vis v.vtype; @@ -3652,7 +2549,7 @@ and childrenVarDecl (vis : cilVisitor) (v : varinfo) : varinfo = v and visitCilVarUse vis v = - doVisitCil vis vis#behavior.get_varinfo vis#vvrbl alphabetabeta v + doVisitCil vis (Visitor_behavior.Get.varinfo vis#behavior) vis#vvrbl alphabetabeta v and visitCilAttributes (vis: cilVisitor) (al: attribute list) : attribute list= let al' = @@ -3726,19 +2623,19 @@ and childrenAttrparam (vis: cilVisitor) (aa: attrparam) : attrparam = let rec fix_succs_preds_block b block = List.iter (fix_succs_preds b) block.bstmts and fix_succs_preds b stmt = - stmt.succs <- mapNoCopy b.get_stmt stmt.succs; - stmt.preds <- mapNoCopy b.get_stmt stmt.preds; + stmt.succs <- mapNoCopy (Visitor_behavior.Get.stmt b) stmt.succs; + stmt.preds <- mapNoCopy (Visitor_behavior.Get.stmt b) stmt.preds; match stmt.skind with If(_,bthen,belse,_) -> fix_succs_preds_block b bthen; fix_succs_preds_block b belse | Switch(e,cases,stmts,l) -> fix_succs_preds_block b cases; - stmt.skind <- Switch(e,cases,List.map b.get_stmt stmts,l) + stmt.skind <- Switch(e,cases,List.map (Visitor_behavior.Get.stmt b) stmts,l) | Loop(annot,block,loc,stmt1,stmt2) -> fix_succs_preds_block b block; - let stmt1' = optMapNoCopy b.get_stmt stmt1 in - let stmt2' = optMapNoCopy b.get_stmt stmt2 in + let stmt1' = optMapNoCopy (Visitor_behavior.Get.stmt b) stmt1 in + let stmt2' = optMapNoCopy (Visitor_behavior.Get.stmt b) stmt2 in stmt.skind <- Loop(annot,block,loc,stmt1',stmt2') | Block block -> fix_succs_preds_block b block | TryFinally(block1,block2,_) -> @@ -3754,7 +2651,7 @@ let rec visitCilFunction (vis : cilVisitor) (f : fundec) : fundec = assertEmptyQueue vis; vis#set_current_func f; (* update fundec tables *) - let f = vis#behavior.memo_fundec f in + let f = Visitor_behavior.Memo.fundec vis#behavior f in let f = doVisitCil vis id (* copy has already been done *) vis#vfunc childrenFunction f @@ -3763,10 +2660,10 @@ let rec visitCilFunction (vis : cilVisitor) (f : fundec) : fundec = if toPrepend <> [] then f.sbody.bstmts <- (List.map (fun i -> mkStmt (Instr i)) toPrepend) @ f.sbody.bstmts; - if vis#behavior.is_copy_behavior then begin + if Visitor_behavior.is_copy vis#behavior then begin fix_succs_preds_block vis#behavior f.sbody; f.sallstmts <- - List.rev (List.rev_map vis#behavior.get_stmt f.sallstmts) + List.rev (List.rev_map (Visitor_behavior.Get.stmt vis#behavior) f.sallstmts) end; vis#reset_current_func (); f @@ -3775,7 +2672,7 @@ and childrenFunction (vis : cilVisitor) (f : fundec) : fundec = (* we have already made a copy of the svar, but not visited it. Use the original variable as argument of visitCilVarDecl, update fundec table in case the vid gets changed. *) - let v = vis#behavior.get_original_varinfo f.svar in + let v = Visitor_behavior.Get_orig.varinfo vis#behavior f.svar in let nv = visitCilVarDecl vis v in if not (Cil_datatype.Varinfo.equal nv f.svar) then begin Kernel.fatal @@ -3789,7 +2686,7 @@ and childrenFunction (vis : cilVisitor) (f : fundec) : fundec = f.slocals <- mapNoCopy (visitCilVarDecl vis) f.slocals; (* Make sure the type reflects the formals *) let selection = State_selection.singleton FormalsDecl.self in - if vis#behavior.is_copy_behavior || newformals != f.sformals then begin + if Visitor_behavior.is_copy vis#behavior || newformals != f.sformals then begin apply_on_project ~selection vis (setFormals f) newformals; end; (* Remember any new instructions that were generated while visiting @@ -3811,8 +2708,8 @@ let childrenFieldInfo vis fi = fi let visitCilFieldInfo vis f = - let f = vis#behavior.get_original_fieldinfo f in - doVisitCil vis vis#behavior.memo_fieldinfo vis#vfieldinfo childrenFieldInfo f + let f = Visitor_behavior.Get_orig.fieldinfo vis#behavior f in + doVisitCil vis (Visitor_behavior.Memo.fieldinfo vis#behavior) vis#vfieldinfo childrenFieldInfo f let childrenCompInfo vis comp = comp.cfields <- mapNoCopy (visitCilFieldInfo vis) comp.cfields; @@ -3820,15 +2717,15 @@ let childrenCompInfo vis comp = comp let visitCilCompInfo vis c = - doVisitCil vis vis#behavior.memo_compinfo vis#vcompinfo childrenCompInfo c + doVisitCil vis (Visitor_behavior.Memo.compinfo vis#behavior) vis#vcompinfo childrenCompInfo c let childrenEnumItem vis e = e.eival <- visitCilExpr vis e.eival; - e.eihost <- vis#behavior.get_enuminfo e.eihost; + e.eihost <- Visitor_behavior.Get.enuminfo vis#behavior e.eihost; e let visitCilEnumItem vis e = - doVisitCil vis vis#behavior.memo_enumitem vis#venumitem childrenEnumItem e + doVisitCil vis (Visitor_behavior.Memo.enumitem vis#behavior) vis#venumitem childrenEnumItem e let childrenEnumInfo vis e = e.eitems <- mapNoCopy (visitCilEnumItem vis) e.eitems; @@ -3836,7 +2733,7 @@ let childrenEnumInfo vis e = e let visitCilEnumInfo vis e = - doVisitCil vis vis#behavior.memo_enuminfo vis#venuminfo childrenEnumInfo e + doVisitCil vis (Visitor_behavior.Memo.enuminfo vis#behavior) vis#venuminfo childrenEnumInfo e let rec visitCilGlobal (vis: cilVisitor) (g: global) : global list = let oldloc = CurrentLoc.get () in @@ -3851,15 +2748,15 @@ and childrenGlobal (vis: cilVisitor) (g: global) : global = let f' = visitCilFunction vis f in if f' != f then GFun (f', l) else g | GType(t, l) -> - let t' = vis#behavior.memo_typeinfo t in + let t' = Visitor_behavior.Memo.typeinfo vis#behavior t in t'.ttype <- visitCilType vis t'.ttype; if t' != t then GType(t',l) else g | GEnumTagDecl (enum,l) -> - let enum' = vis#behavior.memo_enuminfo enum in + let enum' = Visitor_behavior.Memo.enuminfo vis#behavior enum in if enum != enum' then GEnumTagDecl(enum',l) else g (* real visit'll be done in the definition *) | GCompTagDecl (comp,l) -> - let comp' = vis#behavior.memo_compinfo comp in + let comp' = Visitor_behavior.Memo.compinfo vis#behavior comp in if comp != comp' then GCompTagDecl(comp',l) else g | GEnumTag (enum, l) -> let enum' = visitCilEnumInfo vis enum in @@ -3878,7 +2775,7 @@ and childrenGlobal (vis: cilVisitor) (g: global) : global = let form' = optMapNoCopy (mapNoCopy (visitCilVarDecl vis)) form in let spec' = if is_empty_funspec spec then begin - if is_copy_behavior vis#behavior then + if Visitor_behavior.is_copy vis#behavior then empty_funspec () else spec (* do not need to change it if it's not a copy visitor. *) end else begin @@ -3889,7 +2786,7 @@ and childrenGlobal (vis: cilVisitor) (g: global) : global = begin (match form' with | Some formals - when vis#behavior.is_copy_behavior || form != form' -> + when Visitor_behavior.is_copy vis#behavior || form != form' -> let selection = State_selection.singleton FormalsDecl.self in apply_on_project ~selection vis (unsafeSetFormalsDecl v') formals @@ -3899,7 +2796,7 @@ and childrenGlobal (vis: cilVisitor) (g: global) : global = else g | GVar (v, inito, l) -> let v' = visitCilVarDecl vis v in - let inito' = vis#behavior.cinitinfo inito in + let inito' = Visitor_behavior.cinitinfo vis#behavior inito in (match inito'.init with None -> () | Some i -> let i' = visitCilInit vis v NoOffset i in @@ -4242,7 +3139,7 @@ let mkStmtCfg ~before ~(new_stmtkind:stmtkind) ~(ref_stmt:stmt) : stmt = labels = []; sid = -1; succs = []; preds = []; ghost = false; sattr = [] } in - new_.sid <- Sid.next (); + new_.sid <- Cil_const.Sid.next (); if before then begin new_.succs <- [ref_stmt]; let old_preds = ref_stmt.preds in @@ -4271,7 +3168,7 @@ let mkStmtCfg ~before ~(new_stmtkind:stmtkind) ~(ref_stmt:stmt) : stmt = new_ let mkStmtCfgBlock sl = - let sid = Sid.next () in + let sid = Cil_const.Sid.next () in let n = mkStmt (Block (mkBlock sl)) in n.sid <- sid; match sl with @@ -6479,9 +5376,9 @@ let removeOffsetLval ((b, off): lval) : lval * offset = (b, off'), last class copyVisitExpr = object - inherit genericCilVisitor (copy_visit (Project.current ())) + inherit genericCilVisitor (Visitor_behavior.copy (Project.current ())) method! vexpr e = - ChangeDoChildrenPost ({e with eid = Eid.next ()}, fun x -> x) + ChangeDoChildrenPost ({e with eid = Cil_const.Eid.next ()}, fun x -> x) end let copy_exp e = visitCilExpr (new copyVisitExpr) e @@ -6588,11 +5485,11 @@ let post_file vis f = (* A visitor for the whole file that does not change the globals *) let visitCilFileSameGlobals (vis : cilVisitor) (f : file) : unit = - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Kernel.fatal ~current:true "You used visitCilFileSameGlobals with a copy visitor. Nothing is done" else ignore - (doVisitCil vis vis#behavior.cfile (post_file vis) childrenFileSameGlobals f) + (doVisitCil vis (Visitor_behavior.cfile vis#behavior) (post_file vis) childrenFileSameGlobals f) let childrenFileCopy vis f = let fGlob g = visitCilGlobal vis g in @@ -6611,13 +5508,13 @@ let childrenFileCopy vis f = (* Be careful with visiting the whole file because it might be huge. *) let visitCilFileCopy (vis : cilVisitor) (f : file) : file = - if vis#behavior.is_copy_behavior then begin + if Visitor_behavior.is_copy vis#behavior then begin Queue.add Logic_env.prepare_tables vis#get_filling_actions; end; - doVisitCil vis vis#behavior.cfile (post_file vis) childrenFileCopy f + doVisitCil vis (Visitor_behavior.cfile vis#behavior) (post_file vis) childrenFileCopy f let visitCilFile vis f = - if vis#behavior.is_copy_behavior then + if Visitor_behavior.is_copy vis#behavior then Kernel.fatal ~current:true "You used visitCilFile with a copy visitor. Nothing is done" else ignore (visitCilFileCopy vis f) @@ -8084,7 +6981,7 @@ let () = dependency_on_ast Switch_cases.self let separate_switch_succs = Switch_cases.memo separate_switch_succs class dropAttributes ?select () = object - inherit genericCilVisitor (copy_visit (Project.current ())) + inherit genericCilVisitor (Visitor_behavior.copy (Project.current ())) method! vattr a = match select with | None -> ChangeTo [] @@ -8118,6 +7015,7 @@ let typeHasAttributeDeep t = Kernel.deprecated "Cil.typeHasAttributeDeep" ~now:"Cil.typeHasAttributeMemoryBlock" typeHasAttributeMemoryBlock t + (* Local Variables: compile-command: "make -C ../../.." diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli index a2ae37a764d25eea95f19f5bb8db657a711baef7..2c60334fc5ed4d032a1d2c3e885049b7ae99a9d2 100644 --- a/src/kernel_services/ast_queries/cil.mli +++ b/src/kernel_services/ast_queries/cil.mli @@ -234,14 +234,6 @@ val mapGlobals: file -> (global -> global) -> unit * refer to any struct or union types in the function type.*) val findOrCreateFunc: file -> string -> typ -> varinfo -module Sid: sig - val next: unit -> int -end - -module Eid: sig - val next: unit -> int -end - (** creates an expression with a fresh id *) val new_exp: loc:location -> exp_node -> exp @@ -421,34 +413,6 @@ val isSignedInteger: typ -> bool @since Oxygen-20120901 *) val isUnsignedInteger: typ -> bool - -(** Creates a (potentially recursive) composite type. The arguments are: - * (1) a boolean indicating whether it is a struct or a union, (2) the name - * (always non-empty), (3) a function that when given a representation of the - * structure type constructs the type of the fields recursive type (the first - * argument is only useful when some fields need to refer to the type of the - * structure itself), and (4) a list of attributes to be associated with the - * composite type. The resulting compinfo has the field "cdefined" only if - * the list of fields is non-empty. *) -val mkCompInfo: bool -> (* whether it is a struct or a union *) - string -> (* name of the composite type; cannot be empty *) - ?norig:string -> (* original name of the composite type, empty when anonymous *) - (compinfo -> - (string * typ * int option * attributes * location) list) -> - (* a function that when given a forward - representation of the structure type constructs the type of - the fields. The function can ignore this argument if not - constructing a recursive type. *) - attributes -> compinfo - -(** Makes a shallow copy of a {!Cil_types.compinfo} changing the name. It also - copies the fields, and makes sure that the copied field points back to the - copied compinfo. - If [fresh] is [true] (the default), it will also give a fresh id to the - copy. -*) -val copyCompInfo: ?fresh:bool -> compinfo -> string -> compinfo - (** This is a constant used as the name of an unnamed bitfield. These fields do not participate in initialization and their name is not printed. *) val missingFieldName: string @@ -1474,266 +1438,6 @@ val find_default_requires: behavior list -> identified_predicate list (** {2 Visitor mechanism} *) (* ************************************************************************* *) -(** {3 Visitor behavior} *) -type visitor_behavior - (** How the visitor should behave in front of mutable fields: in - place modification or copy of the structure. This type is abstract. - Use one of the two values below in your classes. - @plugin development guide *) - -val inplace_visit: unit -> visitor_behavior - (** In-place modification. Behavior of the original cil visitor. - @plugin development guide *) - -val copy_visit: Project.t -> visitor_behavior - (** Makes fresh copies of the mutable structures. - - preserves sharing for varinfo. - - makes fresh copy of varinfo only for declarations. Variables that are - only used in the visited AST are thus still shared with the original - AST. This allows for instance to copy a function with its - formals and local variables, and to keep the references to other - globals in the function's body. - @plugin development guide *) - -val refresh_visit: Project.t -> visitor_behavior - (** Makes fresh copies of the mutable structures and provides fresh id - for the structures that have ids. Note that as for {!copy_visit}, only - varinfo that are declared in the scope of the visit will be copied and - provided with a new id. - @since Sodium-20150201 - *) - -(** true iff the behavior provides fresh id for copied structs with id. - Always [false] for an inplace visitor. - @since Sodium-20150201 -*) -val is_fresh_behavior: visitor_behavior -> bool - -(** true iff the behavior is a copy behavior. *) -val is_copy_behavior: visitor_behavior -> bool - -val reset_behavior_varinfo: visitor_behavior -> unit -(** resets the internal tables used by the given visitor_behavior. If you use - fresh instances of visitor for each round of transformation, this should - not be needed. In place modifications do not need that at all. - @plugin development guide - *) - -val reset_behavior_compinfo: visitor_behavior -> unit -val reset_behavior_enuminfo: visitor_behavior -> unit -val reset_behavior_enumitem: visitor_behavior -> unit -val reset_behavior_typeinfo: visitor_behavior -> unit -val reset_behavior_stmt: visitor_behavior -> unit -val reset_behavior_logic_info: visitor_behavior -> unit -val reset_behavior_logic_type_info: visitor_behavior -> unit -val reset_behavior_fieldinfo: visitor_behavior -> unit -val reset_behavior_model_info: visitor_behavior -> unit -val reset_logic_var: visitor_behavior -> unit -val reset_behavior_kernel_function: visitor_behavior -> unit -val reset_behavior_fundec: visitor_behavior -> unit - -val get_varinfo: visitor_behavior -> varinfo -> varinfo -(** retrieve the representative of a given varinfo in the current - state of the visitor - @plugin development guide - *) - -val get_compinfo: visitor_behavior -> compinfo -> compinfo -val get_enuminfo: visitor_behavior -> enuminfo -> enuminfo -val get_enumitem: visitor_behavior -> enumitem -> enumitem -val get_typeinfo: visitor_behavior -> typeinfo -> typeinfo -val get_stmt: visitor_behavior -> stmt -> stmt -(** @plugin development guide *) - -val get_logic_info: visitor_behavior -> logic_info -> logic_info -val get_logic_type_info: visitor_behavior -> logic_type_info -> logic_type_info -val get_fieldinfo: visitor_behavior -> fieldinfo -> fieldinfo -val get_model_info: visitor_behavior -> model_info -> model_info -val get_logic_var: visitor_behavior -> logic_var -> logic_var -val get_kernel_function: visitor_behavior -> kernel_function -> kernel_function -(** @plugin development guide *) - -val get_fundec: visitor_behavior -> fundec -> fundec - -val get_original_varinfo: visitor_behavior -> varinfo -> varinfo - (** retrieve the original representative of a given copy of a varinfo - in the current state of the visitor. - @plugin development guide - *) - -val get_original_compinfo: visitor_behavior -> compinfo -> compinfo -val get_original_enuminfo: visitor_behavior -> enuminfo -> enuminfo -val get_original_enumitem: visitor_behavior -> enumitem -> enumitem -val get_original_typeinfo: visitor_behavior -> typeinfo -> typeinfo -val get_original_stmt: visitor_behavior -> stmt -> stmt -val get_original_logic_info: visitor_behavior -> logic_info -> logic_info -val get_original_logic_type_info: - visitor_behavior -> logic_type_info -> logic_type_info -val get_original_fieldinfo: visitor_behavior -> fieldinfo -> fieldinfo -val get_original_model_info: visitor_behavior -> model_info -> model_info -val get_original_logic_var: visitor_behavior -> logic_var -> logic_var -val get_original_kernel_function: - visitor_behavior -> kernel_function -> kernel_function -val get_original_fundec: visitor_behavior -> fundec -> fundec - -val set_varinfo: visitor_behavior -> varinfo -> varinfo -> unit - (** change the representative of a given varinfo in the current - state of the visitor. Use with care (i.e. makes sure that the old one - is not referenced anywhere in the AST, or sharing will be lost. - @plugin development guide - *) -val set_compinfo: visitor_behavior -> compinfo -> compinfo -> unit -val set_enuminfo: visitor_behavior -> enuminfo -> enuminfo -> unit -val set_enumitem: visitor_behavior -> enumitem -> enumitem -> unit -val set_typeinfo: visitor_behavior -> typeinfo -> typeinfo -> unit -val set_stmt: visitor_behavior -> stmt -> stmt -> unit -val set_logic_info: visitor_behavior -> logic_info -> logic_info -> unit -val set_logic_type_info: - visitor_behavior -> logic_type_info -> logic_type_info -> unit -val set_fieldinfo: visitor_behavior -> fieldinfo -> fieldinfo -> unit -val set_model_info: visitor_behavior -> model_info -> model_info -> unit -val set_logic_var: visitor_behavior -> logic_var -> logic_var -> unit -val set_kernel_function: - visitor_behavior -> kernel_function -> kernel_function -> unit -val set_fundec: visitor_behavior -> fundec -> fundec -> unit - -val set_orig_varinfo: visitor_behavior -> varinfo -> varinfo -> unit - (** change the reference of a given new varinfo in the current - state of the visitor. Use with care - *) -val set_orig_compinfo: visitor_behavior -> compinfo -> compinfo -> unit -val set_orig_enuminfo: visitor_behavior -> enuminfo -> enuminfo -> unit -val set_orig_enumitem: visitor_behavior -> enumitem -> enumitem -> unit -val set_orig_typeinfo: visitor_behavior -> typeinfo -> typeinfo -> unit -val set_orig_stmt: visitor_behavior -> stmt -> stmt -> unit -val set_orig_logic_info: visitor_behavior -> logic_info -> logic_info -> unit -val set_orig_logic_type_info: - visitor_behavior -> logic_type_info -> logic_type_info -> unit -val set_orig_fieldinfo: visitor_behavior -> fieldinfo -> fieldinfo -> unit -val set_orig_model_info: visitor_behavior -> model_info -> model_info -> unit -val set_orig_logic_var: visitor_behavior -> logic_var -> logic_var -> unit -val set_orig_kernel_function: - visitor_behavior -> kernel_function -> kernel_function -> unit -val set_orig_fundec: visitor_behavior -> fundec -> fundec -> unit - -val unset_varinfo: visitor_behavior -> varinfo -> unit - (** remove the entry associated to the given varinfo in the current - state of the visitor. Use with care (i.e. make sure that you will never - visit again this varinfo in the same visiting context). - @plugin development guide - *) -val unset_compinfo: visitor_behavior -> compinfo -> unit -val unset_enuminfo: visitor_behavior -> enuminfo -> unit -val unset_enumitem: visitor_behavior -> enumitem -> unit -val unset_typeinfo: visitor_behavior -> typeinfo -> unit -val unset_stmt: visitor_behavior -> stmt -> unit -val unset_logic_info: visitor_behavior -> logic_info -> unit -val unset_logic_type_info: visitor_behavior -> logic_type_info -> unit -val unset_fieldinfo: visitor_behavior -> fieldinfo -> unit -val unset_model_info: visitor_behavior -> model_info -> unit -val unset_logic_var: visitor_behavior -> logic_var -> unit -val unset_kernel_function: visitor_behavior -> kernel_function -> unit -val unset_fundec: visitor_behavior -> fundec -> unit - -val unset_orig_varinfo: visitor_behavior -> varinfo -> unit - (** remove the entry associated with the given new varinfo in the current - state of the visitor. Use with care - *) -val unset_orig_compinfo: visitor_behavior -> compinfo -> unit -val unset_orig_enuminfo: visitor_behavior -> enuminfo -> unit -val unset_orig_enumitem: visitor_behavior -> enumitem -> unit -val unset_orig_typeinfo: visitor_behavior -> typeinfo -> unit -val unset_orig_stmt: visitor_behavior -> stmt -> unit -val unset_orig_logic_info: visitor_behavior -> logic_info -> unit -val unset_orig_logic_type_info: visitor_behavior -> logic_type_info -> unit -val unset_orig_fieldinfo: visitor_behavior -> fieldinfo -> unit -val unset_orig_model_info: visitor_behavior -> model_info -> unit -val unset_orig_logic_var: visitor_behavior -> logic_var -> unit -val unset_orig_kernel_function: visitor_behavior -> kernel_function -> unit -val unset_orig_fundec: visitor_behavior -> fundec -> unit - -val memo_varinfo: visitor_behavior -> varinfo -> varinfo - (** finds a binding in new project for the given varinfo, creating one - if it does not already exists. *) -val memo_compinfo: visitor_behavior -> compinfo -> compinfo -val memo_enuminfo: visitor_behavior -> enuminfo -> enuminfo -val memo_enumitem: visitor_behavior -> enumitem -> enumitem -val memo_typeinfo: visitor_behavior -> typeinfo -> typeinfo -val memo_stmt: visitor_behavior -> stmt -> stmt -val memo_logic_info: visitor_behavior -> logic_info -> logic_info -val memo_logic_type_info: visitor_behavior -> logic_type_info -> logic_type_info -val memo_fieldinfo: visitor_behavior -> fieldinfo -> fieldinfo -val memo_model_info: visitor_behavior -> model_info -> model_info -val memo_logic_var: visitor_behavior -> logic_var -> logic_var -val memo_kernel_function: - visitor_behavior -> kernel_function -> kernel_function -val memo_fundec: visitor_behavior -> fundec -> fundec - -(** [iter_visitor_varinfo vis f] iterates [f] over each pair of - varinfo registered in [vis]. Varinfo for the old AST is presented - to [f] first. - @since Oxygen-20120901 -*) -val iter_visitor_varinfo: - visitor_behavior -> (varinfo -> varinfo -> unit) -> unit -val iter_visitor_compinfo: - visitor_behavior -> (compinfo -> compinfo -> unit) -> unit -val iter_visitor_enuminfo: - visitor_behavior -> (enuminfo -> enuminfo -> unit) -> unit -val iter_visitor_enumitem: - visitor_behavior -> (enumitem -> enumitem -> unit) -> unit -val iter_visitor_typeinfo: - visitor_behavior -> (typeinfo -> typeinfo -> unit) -> unit -val iter_visitor_stmt: - visitor_behavior -> (stmt -> stmt -> unit) -> unit -val iter_visitor_logic_info: - visitor_behavior -> (logic_info -> logic_info -> unit) -> unit -val iter_visitor_logic_type_info: - visitor_behavior -> (logic_type_info -> logic_type_info -> unit) -> unit -val iter_visitor_fieldinfo: - visitor_behavior -> (fieldinfo -> fieldinfo -> unit) -> unit -val iter_visitor_model_info: - visitor_behavior -> (model_info -> model_info -> unit) -> unit -val iter_visitor_logic_var: - visitor_behavior -> (logic_var -> logic_var -> unit) -> unit -val iter_visitor_kernel_function: - visitor_behavior -> (kernel_function -> kernel_function -> unit) -> unit -val iter_visitor_fundec: - visitor_behavior -> (fundec -> fundec -> unit) -> unit - -(** [fold_visitor_varinfo vis f] folds [f] over each pair of varinfo registered - in [vis]. Varinfo for the old AST is presented to [f] first. - @since Oxygen-20120901 -*) -val fold_visitor_varinfo: - visitor_behavior -> (varinfo -> varinfo -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_compinfo: - visitor_behavior -> (compinfo -> compinfo -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_enuminfo: - visitor_behavior -> (enuminfo -> enuminfo -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_enumitem: - visitor_behavior -> (enumitem -> enumitem -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_typeinfo: - visitor_behavior -> (typeinfo -> typeinfo -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_stmt: - visitor_behavior -> (stmt -> stmt -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_logic_info: - visitor_behavior -> (logic_info -> logic_info -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_logic_type_info: - visitor_behavior -> - (logic_type_info -> logic_type_info -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_fieldinfo: - visitor_behavior -> (fieldinfo -> fieldinfo -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_model_info: - visitor_behavior -> (model_info -> model_info -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_logic_var: - visitor_behavior -> (logic_var -> logic_var -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_kernel_function: - visitor_behavior -> - (kernel_function -> kernel_function -> 'a -> 'a) -> 'a -> 'a -val fold_visitor_fundec: - visitor_behavior -> (fundec -> fundec -> 'a -> 'a) -> 'a -> 'a - (** {3 Visitor class} *) (** A visitor interface for traversing CIL trees. Create instantiations of @@ -1750,7 +1454,7 @@ val fold_visitor_fundec: @plugin development guide *) class type cilVisitor = object - method behavior: visitor_behavior + method behavior: Visitor_behavior.t (** the kind of behavior expected for the behavior. @plugin development guide *) @@ -1978,12 +1682,12 @@ val register_behavior_extension: (**/**) class internal_genericCilVisitor: - fundec option ref -> visitor_behavior -> (unit->unit) Queue.t -> cilVisitor + fundec option ref -> Visitor_behavior.t -> (unit->unit) Queue.t -> cilVisitor (**/**) (** generic visitor, parameterized by its copying behavior. Traverses the CIL tree without modifying anything *) -class genericCilVisitor: visitor_behavior -> cilVisitor +class genericCilVisitor: Visitor_behavior.t -> cilVisitor (** Default in place visitor doing nothing and operating on current project. *) class nopCilVisitor: cilVisitor diff --git a/src/kernel_services/ast_queries/cil_const.ml b/src/kernel_services/ast_queries/cil_const.ml index da948c8edd1beb07616fb34b7328f73b7d6b65e9..f11f85dbf1f6ca987cf761d5cc257e3b0a1806f3 100644 --- a/src/kernel_services/ast_queries/cil_const.ml +++ b/src/kernel_services/ast_queries/cil_const.ml @@ -55,6 +55,8 @@ module CurrentLoc = let voidType = TVoid([]) module Vid = State_builder.SharedCounter(struct let name = "vid_counter" end) +module Sid = State_builder.SharedCounter(struct let name = "sid" end) +module Eid = State_builder.SharedCounter(struct let name = "eid" end) let set_vid v = let n = Vid.next () in @@ -79,6 +81,68 @@ let change_varinfo_name vi name = let new_raw_id = Vid.next +(* The next compindo identifier to use. Counts up. *) + let nextCompinfoKey = + let module M = + State_builder.SharedCounter(struct let name = "compinfokey" end) + in + M.next + +(** Creates a (potentially recursive) composite type. Make sure you add a + * GTag for it to the file! **) +let mkCompInfo + (isstruct: bool) + (n: string) + ?(norig=n) + (* fspec is a function that when given a forward + * representation of the structure type constructs the type of + * the fields. The function can ignore this argument if not + * constructing a recursive type. *) + (mkfspec: compinfo -> (string * typ * int option * attribute list * + location) list) + (a: attribute list) : compinfo = + + (* make a new name for anonymous structs *) + if n = "" then Kernel.fatal "mkCompInfo: missing structure name\n" ; + (* Make a new self cell and a forward reference *) + let comp = + { cstruct = isstruct; + corig_name = norig; + cname = n; + ckey = nextCompinfoKey (); + cfields = []; (* fields will be added afterwards. *) + cattr = a; + creferenced = false; + (* Make this compinfo undefined by default *) + cdefined = false; } + in + let flds = + List.map (fun (fn, ft, fb, fa, fl) -> + { fcomp = comp; + ftype = ft; + forig_name = fn; + fname = fn; + fbitfield = fb; + fattr = fa; + floc = fl; + faddrof = false; + fsize_in_bits = None; + foffset_in_bits = None; + fpadding_in_bits = None; + }) (mkfspec comp) in + comp.cfields <- flds; + if flds <> [] then comp.cdefined <- true; + comp + +(** Make a copy of a compinfo, changing the name and the key *) +let copyCompInfo ?(fresh=true) ci cname = + let ckey = if fresh then nextCompinfoKey () else ci.ckey in + let ci' = { ci with cname; ckey } in + (* Copy the fields and set the new pointers to parents *) + ci'.cfields <- List.map (fun f -> {f with fcomp = ci'}) ci'.cfields; + ci' + + let make_logic_var_kind x kind typ = {lv_name = x; lv_id = new_raw_id(); lv_type = typ; lv_kind = kind; lv_origin = None; lv_attr = [] } diff --git a/src/kernel_services/ast_queries/cil_const.mli b/src/kernel_services/ast_queries/cil_const.mli index 0fdc1c5fc996e9a56375763da6953268db13ff0f..58178291430fce395a9cefe0f39f2fa696ba4956 100644 --- a/src/kernel_services/ast_queries/cil_const.mli +++ b/src/kernel_services/ast_queries/cil_const.mli @@ -50,6 +50,8 @@ val voidType: typ module CurrentLoc: State_builder.Ref with type data = location module Vid: sig val next: unit -> int end +module Sid: sig val next: unit -> int end +module Eid: sig val next: unit -> int end (** set the vid to a fresh number. *) val set_vid: varinfo -> unit @@ -72,6 +74,34 @@ val new_raw_id: unit -> int that is generated by {!Cil.makeLocalVar} and friends. Must not be used for setting vid: use {!set_vid} instead. *) +(** Creates a (potentially recursive) composite type. The arguments are: + * (1) a boolean indicating whether it is a struct or a union, (2) the name + * (always non-empty), (3) a function that when given a representation of the + * structure type constructs the type of the fields recursive type (the first + * argument is only useful when some fields need to refer to the type of the + * structure itself), and (4) a list of attributes to be associated with the + * composite type. The resulting compinfo has the field "cdefined" only if + * the list of fields is non-empty. *) +val mkCompInfo: bool -> (* whether it is a struct or a union *) + string -> (* name of the composite type; cannot be empty *) + ?norig:string -> (* original name of the composite type, empty when anonymous *) + (compinfo -> + (string * typ * int option * attributes * location) list) -> + (* a function that when given a forward + representation of the structure type constructs the type of + the fields. The function can ignore this argument if not + constructing a recursive type. *) + attributes -> compinfo + +(** Makes a shallow copy of a {!Cil_types.compinfo} changing the name. It also + copies the fields, and makes sure that the copied field points back to the + copied compinfo. + If [fresh] is [true] (the default), it will also give a fresh id to the + copy. +*) +val copyCompInfo: ?fresh:bool -> compinfo -> string -> compinfo + + (** Create a fresh logical variable giving its name, type and origin. @since Fluorine-20130401 *) diff --git a/src/kernel_services/ast_queries/file.ml b/src/kernel_services/ast_queries/file.ml index 9fd8da5e14f15e9d52bee6b56c65cc7952b1058a..60ee0168a457e35ea8e96e1e344080082729d802 100644 --- a/src/kernel_services/ast_queries/file.ml +++ b/src/kernel_services/ast_queries/file.ml @@ -1567,7 +1567,7 @@ let prepare_from_c_files () = let init_project_from_visitor ?(reorder=false) prj (vis:Visitor.frama_c_visitor) = - if not (Cil.is_copy_behavior vis#behavior) + if not (Visitor_behavior.is_copy vis#behavior) || not (Project.equal prj (Extlib.the vis#project)) then Kernel.fatal diff --git a/src/kernel_services/ast_queries/logic_utils.ml b/src/kernel_services/ast_queries/logic_utils.ml index 7b34794252919a949b016b77e9ce38241abc86a9..fb00eb02fa931eef53384306ea221720419d599f 100644 --- a/src/kernel_services/ast_queries/logic_utils.ml +++ b/src/kernel_services/ast_queries/logic_utils.ml @@ -2513,7 +2513,7 @@ let eval_term_lval global_find_init (lhost, loff) = | _ -> None class simplify_const_lval global_find_init = object (self) - inherit Cil.genericCilVisitor (Cil.copy_visit (Project.current ())) + inherit Cil.genericCilVisitor (Visitor_behavior.copy (Project.current ())) method! vterm t = match t.term_node with diff --git a/src/kernel_services/ast_transformations/filter.ml b/src/kernel_services/ast_transformations/filter.ml index 53907e6dc53d71f21bd0f3866f0a5e6b5a6f39b6..0a24be8541627b5368278c60906916b4780171e4 100644 --- a/src/kernel_services/ast_transformations/filter.ml +++ b/src/kernel_services/ast_transformations/filter.ml @@ -327,7 +327,7 @@ end = struct * *) class filter_visitor pinfo prj = object(self) - inherit Visitor.generic_frama_c_visitor (Cil.copy_visit prj) + inherit Visitor.generic_frama_c_visitor (Visitor_behavior.copy prj) val mutable keep_stmts = Stmt.Set.empty val mutable fi = None @@ -396,13 +396,13 @@ end = struct (fun v -> Varinfo.Hashtbl.add local_visible v (); let v' = Cil.copyVarinfo v v.vname in - Cil.set_varinfo self#behavior v v'; - Cil.set_orig_varinfo self#behavior v' v; + Visitor_behavior.Set.varinfo self#behavior v v'; + Visitor_behavior.Set_orig.varinfo self#behavior v' v; (match v.vlogic_var_assoc, v'.vlogic_var_assoc with None, None -> () | Some lv, Some lv' -> - Cil.set_logic_var self#behavior lv lv'; - Cil.set_orig_logic_var self#behavior lv' lv + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv | _ -> assert false (* copy should be faithful *)); v') formals @@ -418,13 +418,13 @@ end = struct then begin Varinfo.Hashtbl.add local_visible var (); let var' = Cil.copyVarinfo var var.vname in - Cil.set_varinfo self#behavior var var'; - Cil.set_orig_varinfo self#behavior var' var; + Visitor_behavior.Set.varinfo self#behavior var var'; + Visitor_behavior.Set_orig.varinfo self#behavior var' var; (match var.vlogic_var_assoc, var'.vlogic_var_assoc with None, None -> () | Some lv, Some lv' -> - Cil.set_logic_var self#behavior lv lv'; - Cil.set_orig_logic_var self#behavior lv' lv + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv | _ -> assert false (* copy should be faithful *)); var' :: (filter locals) end else filter locals @@ -434,7 +434,8 @@ end = struct method! vcode_annot v = Extlib.may Cil.CurrentLoc.set (Cil_datatype.Code_annotation.loc v); let stmt = - Cil.get_original_stmt self#behavior (Extlib.the self#current_stmt) + Visitor_behavior.Get_orig.stmt + self#behavior (Extlib.the self#current_stmt) in debug "[annotation] stmt %d : %a @." stmt.sid Printer.pp_code_annotation v; @@ -516,14 +517,14 @@ end = struct Cil.ChangeDoChildrenPost (b, optim) method private change_sid s = - let orig = Cil.get_original_stmt self#behavior s in - assert (Cil.get_stmt self#behavior orig == s); + let orig = Visitor_behavior.Get_orig.stmt self#behavior s in + assert (Visitor_behavior.Get.stmt self#behavior orig == s); let old = s.sid in let keep = Stmt.Set.mem s keep_stmts in keep_stmts <- Stmt.Set.remove s keep_stmts; - s.sid <- Cil.Sid.next (); - Cil.set_stmt self#behavior orig s; - Cil.set_orig_stmt self#behavior s orig; + s.sid <- Cil_const.Sid.next (); + Visitor_behavior.Set.stmt self#behavior orig s; + Visitor_behavior.Set_orig.stmt self#behavior s orig; if keep then self#add_stmt_keep s; debug "@[finalize sid:%d->sid:%d@]@\n@." old s.sid @@ -539,7 +540,7 @@ end = struct | If (_,bthen,belse,loc) -> let bthen = Cil.visitCilBlock (self:>Cil.cilVisitor) bthen in let belse = Cil.visitCilBlock (self:>Cil.cilVisitor) belse in - let s_orig = Cil.get_original_stmt self#behavior s in + let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s in optim_if finfo keep_stmts s_orig s None bthen belse loc | Switch (_exp, body, _, loc) -> (* the switch is invisible : it can be translated into a block. *) @@ -561,7 +562,7 @@ end = struct anything to do: it will not appear at all in the function. *) if Info.loc_var_visible (self#get_finfo()) v then begin - let v' = Cil.get_varinfo self#behavior v in + let v' = Visitor_behavior.Get.varinfo self#behavior v in v'.vdefined <- false; end; mk_new_stmt s (mk_stmt_skip s) @@ -584,7 +585,7 @@ end = struct we would have multiple syntactic scope for the same variable). *) method private remove_local_static_attr v = - let new_v = Cil.get_varinfo self#behavior v in + let new_v = Visitor_behavior.Get.varinfo self#behavior v in new_v.vattr <- Cil.dropAttribute Cabs2cil.fc_local_static new_v.vattr method private process_visible_stmt s = @@ -612,7 +613,7 @@ end = struct self#change_sid s'; (match s'.skind with | If (cond,bthen,belse,loc) -> - let s_orig = Cil.get_original_stmt self#behavior s' in + let s_orig = Visitor_behavior.Get_orig.stmt self#behavior s' in optim_if finfo keep_stmts s_orig s' (Some cond) bthen belse loc | Switch (e,b,c,l) -> let c' = List.filter (not $ (can_skip keep_stmts)) c in @@ -703,7 +704,7 @@ end = struct (fun () -> Cil.setFormals f new_formals) self#get_filling_actions; (* clean up the environment if we have more than one copy of the function in the sliced code. *) - Cil.reset_behavior_stmt self#behavior; + Visitor_behavior.Reset.stmt self#behavior; keep_stmts <- Stmt.Set.empty; Varinfo.Hashtbl.clear local_visible; Varinfo.Hashtbl.add spec_table f.svar @@ -822,14 +823,14 @@ end = struct new_var.vtype <- mytype; List.iter2 (fun x y -> - Cil.set_varinfo self#behavior x y; - Cil.set_orig_varinfo self#behavior y x; + Visitor_behavior.Set.varinfo self#behavior x y; + Visitor_behavior.Set_orig.varinfo self#behavior y x; match x.vlogic_var_assoc with None -> (); | Some lv -> let lv' = Cil.cvar_to_lvar y in - Cil.set_logic_var self#behavior lv lv'; - Cil.set_orig_logic_var self#behavior lv' lv) + Visitor_behavior.Set.logic_var self#behavior lv lv'; + Visitor_behavior.Set_orig.logic_var self#behavior lv' lv) old_formals new_formals; (* adds the new parameters to the formals decl table *) @@ -856,15 +857,15 @@ end = struct let orig_var = Ast_info.Function.get_vi kf.fundec in (* The first copy is also the default one for varinfo that are not handled by ff_var but directly by the visitor *) - if (Cil.get_varinfo self#behavior orig_var) == orig_var then - Cil.set_varinfo self#behavior orig_var new_var; + if (Visitor_behavior.Get.varinfo self#behavior orig_var) == orig_var then + Visitor_behavior.Set.varinfo self#behavior orig_var new_var; (* Set the new_var as an already known one, coming from the vi associated to the current kf. *) - Cil.set_varinfo self#behavior new_var new_var; - Cil.set_orig_varinfo self#behavior new_var orig_var; - Cil.set_kernel_function self#behavior kf new_kf; - Cil.set_orig_kernel_function self#behavior new_kf kf; + Visitor_behavior.Set.varinfo self#behavior new_var new_var; + Visitor_behavior.Set_orig.varinfo self#behavior new_var orig_var; + Visitor_behavior.Set.kernel_function self#behavior kf new_kf; + Visitor_behavior.Set_orig.kernel_function self#behavior new_kf kf; Queue.add (fun () -> Globals.Functions.register new_kf) self#get_filling_actions; GFunDecl (Cil.empty_funspec(), new_var, loc), action @@ -902,10 +903,10 @@ end = struct let new_kf = make_new_kf my_kf kf new_fct_var in (* Set the new_var as an already known one, * coming from the vi associated to the current kf. *) - Cil.set_varinfo self#behavior new_fct_var new_fct_var; - Cil.set_orig_varinfo self#behavior new_fct_var fvar; - Cil.set_kernel_function self#behavior kf new_kf; - Cil.set_orig_kernel_function self#behavior new_kf kf; + Visitor_behavior.Set.varinfo self#behavior new_fct_var new_fct_var; + Visitor_behavior.Set_orig.varinfo self#behavior new_fct_var fvar; + Visitor_behavior.Set.kernel_function self#behavior kf new_kf; + Visitor_behavior.Set_orig.kernel_function self#behavior new_kf kf; Queue.add (fun () -> Globals.Functions.register new_kf) self#get_filling_actions; diff --git a/src/kernel_services/ast_transformations/inline.ml b/src/kernel_services/ast_transformations/inline.ml index cb00a64b313a8dc77930c56db256653944770fa7..600438e672790705bcb21a8956246d3539ef92a7 100644 --- a/src/kernel_services/ast_transformations/inline.ml +++ b/src/kernel_services/ast_transformations/inline.ml @@ -90,7 +90,7 @@ let inline_call loc caller callee return args = method! vvrbl v = if v.vglob then - Cil.ChangeTo (Cil.get_original_varinfo self#behavior v) + Cil.ChangeTo (Visitor_behavior.Get_orig.varinfo self#behavior v) else Cil.DoChildren method! vterm_lval (host,offset) = diff --git a/src/kernel_services/visitors/visitor.ml b/src/kernel_services/visitors/visitor.ml index 9e6738a2b39efce81be89b924d4670a5263211d2..01ee6940afea4dd4737b8ffd4b766022dd122065 100644 --- a/src/kernel_services/visitors/visitor.ml +++ b/src/kernel_services/visitors/visitor.ml @@ -66,7 +66,7 @@ object(self) method current_kf = !current_kf method! private vstmt stmt = - let orig_stmt = Cil.get_original_stmt self#behavior stmt in + let orig_stmt = Visitor_behavior.Get_orig.stmt self#behavior stmt in let annots = Annotations.fold_code_annot (fun e a acc -> (e, a) :: acc) orig_stmt [] in @@ -91,7 +91,7 @@ object(self) if [x] is already trivial itself. *) let becomes_trivial = is_trivial y && not (is_trivial x) in let curr_add, remove_curr = - if Cil.is_copy_behavior vis#behavior then + if Visitor_behavior.is_copy vis#behavior then (* Copy visitor. We add [y], except if trivial. No sense in removing [x], since the stmt is a new one. *) (if not becomes_trivial then [e, y] else []), @@ -115,7 +115,7 @@ object(self) let change_stmt stmt (add, remove) = if (add <> [] || remove <> []) then begin let kf = Extlib.the self#current_kf in - let new_kf = Cil.get_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Get.kernel_function self#behavior kf in Queue.add (fun () -> List.iter @@ -173,12 +173,12 @@ object(self) let old_allocates = fold_elt Annotations.fold_allocates in let old_extended = fold_elt Annotations.fold_extended in let b' = - if Cil.is_copy_behavior self#behavior then + if Visitor_behavior.is_copy self#behavior then { b with b_name = b.b_name } else b in let res = self#vbehavior b' in - let new_kf = Cil.get_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Get.kernel_function self#behavior kf in let add_queue a = Queue.add a self#get_filling_actions in let visit_clauses vis f = (* Ensures that we have a table associated to new_kf in Annotations. *) @@ -385,7 +385,7 @@ object(self) method private vfunspec_annot () = let kf = Extlib.the self#current_kf in - let new_kf = Cil.get_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Get.kernel_function self#behavior kf in let old_behaviors = Annotations.fold_behaviors (fun e b acc -> (e,b)::acc) kf [] in @@ -625,18 +625,18 @@ object(self) method! vglob g = let fundec, has_kf = match g with | GFunDecl(_,v,_) -> - let ov = Cil.get_original_varinfo self#behavior v in + let ov = Visitor_behavior.Get_orig.varinfo self#behavior v in let kf = try Globals.Functions.get ov with Not_found -> Kernel.fatal "No kernel function for %s(%d)" v.vname v.vid in (* Just make a copy of current kernel function in case it is needed *) - let new_kf = Cil.memo_kernel_function self#behavior kf in - if Cil.is_copy_behavior self#behavior then + let new_kf = Visitor_behavior.Memo.kernel_function self#behavior kf in + if Visitor_behavior.is_copy self#behavior then new_kf.spec <- Cil.empty_funspec (); self#set_current_kf kf; None, true | GFun(f,_) -> - let v = Cil.get_original_varinfo self#behavior f.svar in + let v = Visitor_behavior.Get_orig.varinfo self#behavior f.svar in let kf = try Globals.Functions.get v with Not_found -> @@ -644,8 +644,8 @@ object(self) v.vname Project.pretty (Project.current ()) in - let new_kf = Cil.memo_kernel_function self#behavior kf in - if Cil.is_copy_behavior self#behavior then + let new_kf = Visitor_behavior.Memo.kernel_function self#behavior kf in + if Visitor_behavior.is_copy self#behavior then new_kf.spec <- Cil.empty_funspec (); self#set_current_kf kf; Some f, true @@ -672,7 +672,7 @@ object(self) | _ -> None in let change_glob ng spec = - let cond = is_copy_behavior self#behavior in + let cond = Visitor_behavior.is_copy self#behavior in match ng with | GVar(vi,init,_) -> if cond then @@ -689,7 +689,7 @@ object(self) | GFunDecl(_,v,l) -> (match self#current_kf with | Some kf -> - let new_kf = Cil.get_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Get.kernel_function self#behavior kf in if cond then begin Queue.add (fun () -> @@ -743,7 +743,7 @@ object(self) if cond then begin match self#current_kf with | Some kf -> - let new_kf = Cil.get_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Get.kernel_function self#behavior kf in Queue.add (fun () -> Kernel.debug ~dkey:Kernel.dkey_visitor @@ -836,11 +836,14 @@ class generic_frama_c_visitor bhv = let queue = Queue.create () in internal_generic_frama_c_visitor current_fundec queue current_kf bhv -class frama_c_copy prj = generic_frama_c_visitor (copy_visit prj) +class frama_c_copy prj = + generic_frama_c_visitor (Visitor_behavior.copy prj) -class frama_c_refresh prj = generic_frama_c_visitor (refresh_visit prj) +class frama_c_refresh prj = + generic_frama_c_visitor (Visitor_behavior.refresh prj) -class frama_c_inplace = generic_frama_c_visitor (inplace_visit()) +class frama_c_inplace = + generic_frama_c_visitor (Visitor_behavior.inplace()) let visitFramacFileCopy vis f = visitCilFileCopy (vis:>cilVisitor) f @@ -854,7 +857,7 @@ let visitFramacGlobal vis g = vis#fill_global_tables; g' let visitFramacFunction vis f = - let orig_var = Cil.get_original_varinfo vis#behavior f.svar in + let orig_var = Visitor_behavior.Get_orig.varinfo vis#behavior f.svar in let old_current_kf = vis#current_kf in vis#set_current_kf (Globals.Functions.get orig_var); let f' = visitCilFunction (vis:>cilVisitor) f in @@ -869,7 +872,7 @@ let visitFramacKf vis kf = | None -> kf | Some prj -> let vi = Kernel_function.get_vi kf in - let vi' = Cil.get_varinfo vis#behavior vi in + let vi' = Visitor_behavior.Get.varinfo vis#behavior vi in Project.on prj Globals.Functions.get vi' let visitFramacExpr vis e = diff --git a/src/kernel_services/visitors/visitor.mli b/src/kernel_services/visitors/visitor.mli index 3fffe6a974c20e101b8ec86108f970214b55c417..faa4d4be3a64ce614003527f3601057cadab68ba 100644 --- a/src/kernel_services/visitors/visitor.mli +++ b/src/kernel_services/visitors/visitor.mli @@ -95,7 +95,7 @@ class frama_c_refresh: Project.t -> frama_c_visitor *) class generic_frama_c_visitor: - Cil.visitor_behavior -> frama_c_visitor + Visitor_behavior.t -> frama_c_visitor (** Generic class that abstracts over [frama_c_inplace] and [frama_c_copy]. @plugin development guide *) diff --git a/src/kernel_services/visitors/visitor_behavior.ml b/src/kernel_services/visitors/visitor_behavior.ml new file mode 100644 index 0000000000000000000000000000000000000000..9bff52e7fb21295bd5ae4a623297cd35e781088a --- /dev/null +++ b/src/kernel_services/visitors/visitor_behavior.ml @@ -0,0 +1,1146 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* INRIA (Institut National de Recherche en Informatique et en *) +(* Automatique) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +open Cil_types + +type t = + { (* copy mutable structure which are not shared across the AST*) + cfile: file -> file; + cinitinfo: initinfo -> initinfo; + cblock: block -> block; + cfunspec: funspec -> funspec; + cfunbehavior: funbehavior -> funbehavior; + cidentified_term: identified_term -> identified_term; + cidentified_predicate: identified_predicate -> identified_predicate; + cexpr: exp -> exp; + ccode_annotation: code_annotation -> code_annotation; + (* get the copy of a shared value *) + get_stmt: stmt -> stmt; + get_compinfo: compinfo -> compinfo; + get_fieldinfo: fieldinfo -> fieldinfo; + get_model_info: model_info -> model_info; + get_enuminfo: enuminfo -> enuminfo; + get_enumitem: enumitem -> enumitem; + get_typeinfo: typeinfo -> typeinfo; + get_varinfo: varinfo -> varinfo; + get_logic_info: logic_info -> logic_info; + get_logic_type_info: logic_type_info -> logic_type_info; + get_logic_var: logic_var -> logic_var; + get_kernel_function: kernel_function -> kernel_function; + get_fundec: fundec -> fundec; + (* get the original value tied to a copy *) + get_original_stmt: stmt -> stmt; + get_original_compinfo: compinfo -> compinfo; + get_original_fieldinfo: fieldinfo -> fieldinfo; + get_original_model_info: model_info -> model_info; + get_original_enuminfo: enuminfo -> enuminfo; + get_original_enumitem: enumitem -> enumitem; + get_original_typeinfo: typeinfo -> typeinfo; + get_original_varinfo: varinfo -> varinfo; + get_original_logic_info: logic_info -> logic_info; + get_original_logic_type_info: logic_type_info -> logic_type_info; + get_original_logic_var: logic_var -> logic_var; + get_original_kernel_function: kernel_function -> kernel_function; + get_original_fundec: fundec -> fundec; + (* change a binding... use with care *) + set_stmt: stmt -> stmt -> unit; + set_compinfo: compinfo -> compinfo -> unit; + set_fieldinfo: fieldinfo -> fieldinfo -> unit; + set_model_info: model_info -> model_info -> unit; + set_enuminfo: enuminfo -> enuminfo -> unit; + set_enumitem: enumitem -> enumitem -> unit; + set_typeinfo: typeinfo -> typeinfo -> unit; + set_varinfo: varinfo -> varinfo -> unit; + set_logic_info: logic_info -> logic_info -> unit; + set_logic_type_info: logic_type_info -> logic_type_info -> unit; + set_logic_var: logic_var -> logic_var -> unit; + set_kernel_function: kernel_function -> kernel_function -> unit; + set_fundec: fundec -> fundec -> unit; + (* change a reference... use with care *) + set_orig_stmt: stmt -> stmt -> unit; + set_orig_compinfo: compinfo -> compinfo -> unit; + set_orig_fieldinfo: fieldinfo -> fieldinfo -> unit; + set_orig_model_info: model_info -> model_info -> unit; + set_orig_enuminfo: enuminfo -> enuminfo -> unit; + set_orig_enumitem: enumitem -> enumitem -> unit; + set_orig_typeinfo: typeinfo -> typeinfo -> unit; + set_orig_varinfo: varinfo -> varinfo -> unit; + set_orig_logic_info: logic_info -> logic_info -> unit; + set_orig_logic_type_info: logic_type_info -> logic_type_info -> unit; + set_orig_logic_var: logic_var -> logic_var -> unit; + set_orig_kernel_function: kernel_function -> kernel_function -> unit; + set_orig_fundec: fundec -> fundec -> unit; + + unset_varinfo: varinfo -> unit; + unset_compinfo: compinfo -> unit; + unset_enuminfo: enuminfo -> unit; + unset_enumitem: enumitem -> unit; + unset_typeinfo: typeinfo -> unit; + unset_stmt: stmt -> unit; + unset_logic_info: logic_info -> unit; + unset_logic_type_info: logic_type_info -> unit; + unset_fieldinfo: fieldinfo -> unit; + unset_model_info: model_info -> unit; + unset_logic_var: logic_var -> unit; + unset_kernel_function: kernel_function -> unit; + unset_fundec: fundec -> unit; + + unset_orig_varinfo: varinfo -> unit; + unset_orig_compinfo: compinfo -> unit; + unset_orig_enuminfo: enuminfo -> unit; + unset_orig_enumitem: enumitem -> unit; + unset_orig_typeinfo: typeinfo -> unit; + unset_orig_stmt: stmt -> unit; + unset_orig_logic_info: logic_info -> unit; + unset_orig_logic_type_info: logic_type_info -> unit; + unset_orig_fieldinfo: fieldinfo -> unit; + unset_orig_model_info: model_info -> unit; + unset_orig_logic_var: logic_var -> unit; + unset_orig_kernel_function: kernel_function -> unit; + unset_orig_fundec: fundec -> unit; + + (* copy fields that can referenced in other places of the AST*) + memo_stmt: stmt -> stmt; + memo_varinfo: varinfo -> varinfo; + memo_compinfo: compinfo -> compinfo; + memo_model_info: model_info -> model_info; + memo_enuminfo: enuminfo -> enuminfo; + memo_enumitem: enumitem -> enumitem; + memo_typeinfo: typeinfo -> typeinfo; + memo_logic_info: logic_info -> logic_info; + memo_logic_type_info: logic_type_info -> logic_type_info; + memo_fieldinfo: fieldinfo -> fieldinfo; + memo_logic_var: logic_var -> logic_var; + memo_kernel_function: kernel_function -> kernel_function; + memo_fundec: fundec -> fundec; + (* is the behavior a copy behavior *) + is_copy_behavior: bool; + is_fresh_behavior: bool; + project: Project.t option; + (* reset memoizing tables *) + reset_behavior_varinfo: unit -> unit; + reset_behavior_compinfo: unit -> unit; + reset_behavior_enuminfo: unit -> unit; + reset_behavior_enumitem: unit -> unit; + reset_behavior_typeinfo: unit -> unit; + reset_behavior_logic_info: unit -> unit; + reset_behavior_logic_type_info: unit -> unit; + reset_behavior_fieldinfo: unit -> unit; + reset_behavior_model_info: unit -> unit; + reset_behavior_stmt: unit -> unit; + reset_logic_var: unit -> unit; + reset_behavior_kernel_function: unit -> unit; + reset_behavior_fundec: unit -> unit; + (* iterates over tables *) + iter_visitor_varinfo: (varinfo -> varinfo -> unit) -> unit; + iter_visitor_compinfo: (compinfo -> compinfo -> unit) -> unit; + iter_visitor_enuminfo: (enuminfo -> enuminfo -> unit) -> unit; + iter_visitor_enumitem: (enumitem -> enumitem -> unit) -> unit; + iter_visitor_typeinfo: (typeinfo -> typeinfo -> unit) -> unit; + iter_visitor_stmt: (stmt -> stmt -> unit) -> unit; + iter_visitor_logic_info: (logic_info -> logic_info -> unit) -> unit; + iter_visitor_logic_type_info: + (logic_type_info -> logic_type_info -> unit) -> unit; + iter_visitor_fieldinfo: (fieldinfo -> fieldinfo -> unit) -> unit; + iter_visitor_model_info: (model_info -> model_info -> unit) -> unit; + iter_visitor_logic_var: (logic_var -> logic_var -> unit) -> unit; + iter_visitor_kernel_function: + (kernel_function -> kernel_function -> unit) -> unit; + iter_visitor_fundec: (fundec -> fundec -> unit) -> unit; + (* folds over tables *) + fold_visitor_varinfo: 'a.(varinfo -> varinfo -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_compinfo: 'a.(compinfo -> compinfo -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_enuminfo: 'a.(enuminfo -> enuminfo -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_enumitem: 'a.(enumitem -> enumitem -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_typeinfo: 'a.(typeinfo -> typeinfo -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_stmt: 'a.(stmt -> stmt -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_logic_info: + 'a. (logic_info -> logic_info -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_logic_type_info: + 'a.(logic_type_info -> logic_type_info -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_fieldinfo: + 'a.(fieldinfo -> fieldinfo -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_model_info: + 'a. (model_info -> model_info -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_logic_var: + 'a.(logic_var -> logic_var -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_kernel_function: + 'a.(kernel_function -> kernel_function -> 'a -> 'a) -> 'a -> 'a; + fold_visitor_fundec: + 'a.(fundec -> fundec -> 'a -> 'a) -> 'a -> 'a; + } + +let id = Extlib.id +let alphabetaunit _ _ = () +let alphabetabeta _ x = x +let unitunit: unit -> unit = id +let alphaunit _ = () + +let inplace () = + { cfile = id; + get_compinfo = id; + get_fieldinfo = id; + get_model_info = id; + get_enuminfo = id; + get_enumitem = id; + get_typeinfo = id; + get_varinfo = id; + get_logic_var = id; + get_stmt = id; + get_logic_info = id; + get_logic_type_info = id; + get_kernel_function = id; + get_fundec = id; + get_original_compinfo = id; + get_original_fieldinfo = id; + get_original_model_info = id; + get_original_enuminfo = id; + get_original_enumitem = id; + get_original_typeinfo = id; + get_original_varinfo = id; + get_original_logic_var = id; + get_original_stmt = id; + get_original_logic_info = id; + get_original_logic_type_info = id; + get_original_kernel_function = id; + get_original_fundec = id; + cinitinfo = id; + cblock = id; + cfunspec = id; + cfunbehavior = id; + cidentified_term = id; + cidentified_predicate = id; + ccode_annotation = id; + cexpr = id; + is_copy_behavior = false; + is_fresh_behavior = false; + project = None; + memo_varinfo = id; + memo_compinfo = id; + memo_enuminfo = id; + memo_enumitem = id; + memo_typeinfo = id; + memo_logic_info = id; + memo_logic_type_info = id; + memo_stmt = id; + memo_fieldinfo = id; + memo_model_info = id; + memo_logic_var = id; + memo_kernel_function = id; + memo_fundec = id; + set_varinfo = alphabetaunit; + set_compinfo = alphabetaunit; + set_enuminfo = alphabetaunit; + set_enumitem = alphabetaunit; + set_typeinfo = alphabetaunit; + set_logic_info = alphabetaunit; + set_logic_type_info = alphabetaunit; + set_stmt = alphabetaunit; + set_fieldinfo = alphabetaunit; + set_model_info = alphabetaunit; + set_logic_var = alphabetaunit; + set_kernel_function = alphabetaunit; + set_fundec = alphabetaunit; + set_orig_varinfo = alphabetaunit; + set_orig_compinfo = alphabetaunit; + set_orig_enuminfo = alphabetaunit; + set_orig_enumitem = alphabetaunit; + set_orig_typeinfo = alphabetaunit; + set_orig_logic_info = alphabetaunit; + set_orig_logic_type_info = alphabetaunit; + set_orig_stmt = alphabetaunit; + set_orig_fieldinfo = alphabetaunit; + set_orig_model_info = alphabetaunit; + set_orig_logic_var = alphabetaunit; + set_orig_kernel_function = alphabetaunit; + set_orig_fundec = alphabetaunit; + unset_varinfo = alphaunit; + unset_compinfo = alphaunit; + unset_enuminfo = alphaunit; + unset_enumitem = alphaunit; + unset_typeinfo = alphaunit; + unset_logic_info = alphaunit; + unset_logic_type_info = alphaunit; + unset_stmt = alphaunit; + unset_fieldinfo = alphaunit; + unset_model_info = alphaunit; + unset_logic_var = alphaunit; + unset_kernel_function = alphaunit; + unset_fundec = alphaunit; + unset_orig_varinfo = alphaunit; + unset_orig_compinfo = alphaunit; + unset_orig_enuminfo = alphaunit; + unset_orig_enumitem = alphaunit; + unset_orig_typeinfo = alphaunit; + unset_orig_logic_info = alphaunit; + unset_orig_logic_type_info = alphaunit; + unset_orig_stmt = alphaunit; + unset_orig_fieldinfo = alphaunit; + unset_orig_model_info = alphaunit; + unset_orig_logic_var = alphaunit; + unset_orig_kernel_function = alphaunit; + unset_orig_fundec = alphaunit; + reset_behavior_varinfo = unitunit; + reset_behavior_compinfo = unitunit; + reset_behavior_enuminfo = unitunit; + reset_behavior_enumitem = unitunit; + reset_behavior_typeinfo = unitunit; + reset_behavior_logic_info = unitunit; + reset_behavior_logic_type_info = unitunit; + reset_behavior_fieldinfo = unitunit; + reset_behavior_model_info = unitunit; + reset_behavior_stmt = unitunit; + reset_logic_var = unitunit; + reset_behavior_kernel_function = unitunit; + reset_behavior_fundec = unitunit; + iter_visitor_varinfo = alphaunit; + iter_visitor_compinfo = alphaunit; + iter_visitor_enuminfo = alphaunit; + iter_visitor_enumitem = alphaunit; + iter_visitor_typeinfo = alphaunit; + iter_visitor_stmt = alphaunit; + iter_visitor_logic_info = alphaunit; + iter_visitor_logic_type_info = alphaunit; + iter_visitor_fieldinfo = alphaunit; + iter_visitor_model_info = alphaunit; + iter_visitor_logic_var = alphaunit; + iter_visitor_kernel_function = alphaunit; + iter_visitor_fundec = alphaunit; + fold_visitor_varinfo = alphabetabeta; + fold_visitor_compinfo = alphabetabeta; + fold_visitor_enuminfo = alphabetabeta; + fold_visitor_enumitem = alphabetabeta; + fold_visitor_typeinfo = alphabetabeta; + fold_visitor_stmt = alphabetabeta; + fold_visitor_logic_info = alphabetabeta; + fold_visitor_logic_type_info = alphabetabeta; + fold_visitor_fieldinfo = alphabetabeta; + fold_visitor_model_info = alphabetabeta; + fold_visitor_logic_var = alphabetabeta; + fold_visitor_kernel_function = alphabetabeta; + fold_visitor_fundec = alphabetabeta; + } + +let copy_visit_gen fresh prj = + let varinfos = Cil_datatype.Varinfo.Hashtbl.create 103 in + let compinfos = Cil_datatype.Compinfo.Hashtbl.create 17 in + let enuminfos = Cil_datatype.Enuminfo.Hashtbl.create 17 in + let enumitems = Cil_datatype.Enumitem.Hashtbl.create 17 in + let typeinfos = Cil_datatype.Typeinfo.Hashtbl.create 17 in + let logic_infos = Cil_datatype.Logic_info.Hashtbl.create 17 in + let logic_type_infos = Cil_datatype.Logic_type_info.Hashtbl.create 17 in + let fieldinfos = Cil_datatype.Fieldinfo.Hashtbl.create 17 in + let model_infos = Cil_datatype.Model_info.Hashtbl.create 17 in + let stmts = Cil_datatype.Stmt.Hashtbl.create 103 in + let logic_vars = Cil_datatype.Logic_var.Hashtbl.create 17 in + let kernel_functions = Cil_datatype.Kf.Hashtbl.create 17 in + let fundecs = Cil_datatype.Varinfo.Hashtbl.create 17 in + let orig_varinfos = Cil_datatype.Varinfo.Hashtbl.create 103 in + let orig_compinfos = Cil_datatype.Compinfo.Hashtbl.create 17 in + let orig_enuminfos = Cil_datatype.Enuminfo.Hashtbl.create 17 in + let orig_enumitems = Cil_datatype.Enumitem.Hashtbl.create 17 in + let orig_typeinfos = Cil_datatype.Typeinfo.Hashtbl.create 17 in + let orig_logic_infos = Cil_datatype.Logic_info.Hashtbl.create 17 in + let orig_logic_type_infos = Cil_datatype.Logic_type_info.Hashtbl.create 17 in + let orig_fieldinfos = Cil_datatype.Fieldinfo.Hashtbl.create 17 in + let orig_model_infos = Cil_datatype.Model_info.Hashtbl.create 17 in + let orig_stmts = Cil_datatype.Stmt.Hashtbl.create 103 in + let orig_logic_vars = Cil_datatype.Logic_var.Hashtbl.create 17 in + let orig_kernel_functions = Cil_datatype.Kf.Hashtbl.create 17 in + let orig_fundecs = Cil_datatype.Varinfo.Hashtbl.create 17 in + let temp_set_logic_var x new_x = + Cil_datatype.Logic_var.Hashtbl.add logic_vars x new_x + in + let temp_set_orig_logic_var new_x x = + Cil_datatype.Logic_var.Hashtbl.add orig_logic_vars new_x x + in + let temp_unset_logic_var x = + Cil_datatype.Logic_var.Hashtbl.remove logic_vars x + in + let temp_unset_orig_logic_var new_x = + Cil_datatype.Logic_var.Hashtbl.remove orig_logic_vars new_x + in + let temp_memo_logic_var x = + (* Format.printf "search for %s#%d@." x.lv_name x.lv_id;*) + let res = + try Cil_datatype.Logic_var.Hashtbl.find logic_vars x + with Not_found -> + (* Format.printf "Not found@.";*) + let id = if fresh then Cil_const.new_raw_id () else x.lv_id in + let new_x = { x with lv_id = id } in + temp_set_logic_var x new_x; temp_set_orig_logic_var new_x x; new_x + in + (* Format.printf "res is %s#%d@." res.lv_name res.lv_id;*) + res + in + let temp_set_varinfo x new_x = + Cil_datatype.Varinfo.Hashtbl.add varinfos x new_x; + match x.vlogic_var_assoc, new_x.vlogic_var_assoc with + | None, _ | _, None -> () + | Some lx, Some new_lx -> + Cil_datatype.Logic_var.Hashtbl.add logic_vars lx new_lx + in + let temp_set_orig_varinfo new_x x = + Cil_datatype.Varinfo.Hashtbl.add orig_varinfos new_x x; + match new_x.vlogic_var_assoc, x.vlogic_var_assoc with + | None, _ | _, None -> () + | Some new_lx, Some lx -> + Cil_datatype.Logic_var.Hashtbl.add orig_logic_vars new_lx lx + in + let temp_unset_varinfo x = + Cil_datatype.Varinfo.Hashtbl.remove varinfos x; + match x.vlogic_var_assoc with + | None -> () + | Some lx -> Cil_datatype.Logic_var.Hashtbl.remove logic_vars lx + in + let temp_unset_orig_varinfo new_x = + Cil_datatype.Varinfo.Hashtbl.remove orig_varinfos new_x; + match new_x.vlogic_var_assoc with + | None -> () + | Some new_lx -> + Cil_datatype.Logic_var.Hashtbl.remove orig_logic_vars new_lx + in + let temp_memo_varinfo x = + try Cil_datatype.Varinfo.Hashtbl.find varinfos x + with Not_found -> + let new_x = + if fresh then Cil_const.copy_with_new_vid x else begin + let new_x = { x with vid = x.vid } in + (match x.vlogic_var_assoc with + | None -> () + | Some lv -> + let new_lv = { lv with lv_origin = Some new_x } in + new_x.vlogic_var_assoc <- Some new_lv); + new_x + end + in + temp_set_varinfo x new_x; temp_set_orig_varinfo new_x x; new_x + in + let temp_set_fundec f new_f = + Cil_datatype.Varinfo.Hashtbl.add fundecs f.svar new_f + in + let temp_set_orig_fundec new_f f = + Cil_datatype.Varinfo.Hashtbl.add orig_fundecs new_f.svar f + in + let temp_unset_fundec f = + Cil_datatype.Varinfo.Hashtbl.remove fundecs f.svar + in + let temp_unset_orig_fundec new_f = + Cil_datatype.Varinfo.Hashtbl.remove orig_fundecs new_f.svar + in + let temp_memo_fundec f = + try Cil_datatype.Varinfo.Hashtbl.find fundecs f.svar + with Not_found -> + let v = temp_memo_varinfo f.svar in + let new_f = { f with svar = v } in + temp_set_fundec f new_f; temp_set_orig_fundec new_f f; new_f + in + let temp_set_kernel_function kf new_kf = + Cil_datatype.Kf.Hashtbl.replace kernel_functions kf new_kf; + match kf.fundec, new_kf.fundec with + | Declaration(_,vi,_,_), Declaration(_,new_vi,_,_) + | Declaration(_,vi,_,_), Definition({ svar = new_vi }, _) + | Definition({svar = vi},_), Declaration(_,new_vi,_,_) -> + temp_set_varinfo vi new_vi + | Definition (fundec,_), Definition(new_fundec,_) -> + temp_set_fundec fundec new_fundec + in + let temp_set_orig_kernel_function new_kf kf = + Cil_datatype.Kf.Hashtbl.replace orig_kernel_functions new_kf kf; + match new_kf.fundec, kf.fundec with + | Declaration(_,new_vi,_,_), Declaration(_,vi,_,_) + | Declaration(_,new_vi,_,_), Definition({ svar = vi }, _) + | Definition({svar = new_vi},_), Declaration(_,vi,_,_) -> + temp_set_orig_varinfo new_vi vi + | Definition (new_fundec,_), Definition(fundec,_) -> + temp_set_orig_fundec new_fundec fundec + in + let temp_unset_kernel_function kf = + Cil_datatype.Kf.Hashtbl.remove kernel_functions kf; + match kf.fundec with + | Declaration(_,vi,_,_) -> temp_unset_varinfo vi + | Definition (fundec,_) -> temp_unset_fundec fundec + in + let temp_unset_orig_kernel_function new_kf = + Cil_datatype.Kf.Hashtbl.remove orig_kernel_functions new_kf; + match new_kf.fundec with + | Declaration(_,new_vi,_,_) -> temp_unset_orig_varinfo new_vi + | Definition (new_fundec,_) -> temp_unset_orig_fundec new_fundec + in + let temp_memo_kernel_function kf = + try Cil_datatype.Kf.Hashtbl.find kernel_functions kf + with Not_found -> + let new_kf = + match kf.fundec with + | Declaration (spec,vi,prms,loc) -> + let new_vi = temp_memo_varinfo vi in + { kf with fundec = Declaration(spec,new_vi,prms,loc) } + | Definition(f,loc) -> + let new_f = temp_memo_fundec f in + { kf with fundec = Definition(new_f,loc) } + in + temp_set_kernel_function kf new_kf; + temp_set_orig_kernel_function new_kf kf; + new_kf + in + let temp_set_compinfo c new_c = + Cil_datatype.Compinfo.Hashtbl.add compinfos c new_c; + List.iter2 + (fun f new_f -> Cil_datatype.Fieldinfo.Hashtbl.add fieldinfos f new_f) + c.cfields new_c.cfields + in + let temp_set_orig_compinfo new_c c = + Cil_datatype.Compinfo.Hashtbl.add orig_compinfos new_c c; + List.iter2 + (fun new_f f -> + Cil_datatype.Fieldinfo.Hashtbl.add orig_fieldinfos new_f f) + new_c.cfields c.cfields + in + let temp_unset_compinfo c = + Cil_datatype.Compinfo.Hashtbl.remove compinfos c; + List.iter + (fun f -> Cil_datatype.Fieldinfo.Hashtbl.remove fieldinfos f) c.cfields + in + let temp_unset_orig_compinfo new_c = + Cil_datatype.Compinfo.Hashtbl.remove orig_compinfos new_c; + List.iter + (fun new_f -> + Cil_datatype.Fieldinfo.Hashtbl.remove orig_fieldinfos new_f) + new_c.cfields + in + let temp_memo_compinfo c = + try Cil_datatype.Compinfo.Hashtbl.find compinfos c + with Not_found -> + let new_c = + Cil_const.copyCompInfo ~fresh c c.cname + in + temp_set_compinfo c new_c; temp_set_orig_compinfo new_c c; new_c + in + { cfile = (fun x -> { x with fileName = x.fileName }); + get_compinfo = + (fun x -> + try Cil_datatype.Compinfo.Hashtbl.find compinfos x with Not_found -> x); + get_fieldinfo = + (fun x -> + try Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x + with Not_found -> x); + get_model_info = + (fun x -> + try Cil_datatype.Model_info.Hashtbl.find model_infos x + with Not_found -> x); + get_enuminfo = + (fun x -> + try Cil_datatype.Enuminfo.Hashtbl.find enuminfos x with Not_found -> x); + get_enumitem = + (fun x -> + try Cil_datatype.Enumitem.Hashtbl.find enumitems x with Not_found -> x); + get_typeinfo = + (fun x -> + try Cil_datatype.Typeinfo.Hashtbl.find typeinfos x with Not_found -> x); + get_varinfo = + (fun x -> + try Cil_datatype.Varinfo.Hashtbl.find varinfos x with Not_found -> x); + get_stmt = + (fun x -> try Cil_datatype.Stmt.Hashtbl.find stmts x with Not_found -> x); + get_logic_info = + (fun x -> + try Cil_datatype.Logic_info.Hashtbl.find logic_infos x + with Not_found -> x); + get_logic_type_info = + (fun x -> + try Cil_datatype.Logic_type_info.Hashtbl.find logic_type_infos x + with Not_found -> x); + get_logic_var = + (fun x -> + try Cil_datatype.Logic_var.Hashtbl.find logic_vars x + with Not_found -> x); + get_kernel_function = + (fun x -> + try Cil_datatype.Kf.Hashtbl.find kernel_functions x + with Not_found -> x); + get_fundec = + (fun x -> + try Cil_datatype.Varinfo.Hashtbl.find fundecs x.svar + with Not_found -> x); + get_original_compinfo = + (fun x -> + try Cil_datatype.Compinfo.Hashtbl.find orig_compinfos x + with Not_found -> x); + get_original_fieldinfo = + (fun x -> + try Cil_datatype.Fieldinfo.Hashtbl.find orig_fieldinfos x + with Not_found -> x); + get_original_model_info = + (fun x -> + try Cil_datatype.Model_info.Hashtbl.find orig_model_infos x + with Not_found -> x); + get_original_enuminfo = + (fun x -> + try Cil_datatype.Enuminfo.Hashtbl.find orig_enuminfos x + with Not_found -> x); + get_original_enumitem = + (fun x -> + try Cil_datatype.Enumitem.Hashtbl.find orig_enumitems x + with Not_found -> x); + get_original_typeinfo = + (fun x -> + try Cil_datatype.Typeinfo.Hashtbl.find orig_typeinfos x + with Not_found -> x); + get_original_varinfo = + (fun x -> + try Cil_datatype.Varinfo.Hashtbl.find orig_varinfos x + with Not_found -> x); + get_original_stmt = + (fun x -> + try Cil_datatype.Stmt.Hashtbl.find orig_stmts x with Not_found -> x); + get_original_logic_var = + (fun x -> + try Cil_datatype.Logic_var.Hashtbl.find orig_logic_vars x + with Not_found -> x); + get_original_logic_info = + (fun x -> + try Cil_datatype.Logic_info.Hashtbl.find orig_logic_infos x + with Not_found -> x); + get_original_logic_type_info = + (fun x -> + try Cil_datatype.Logic_type_info.Hashtbl.find orig_logic_type_infos x + with Not_found -> x); + get_original_kernel_function = + (fun x -> + try Cil_datatype.Kf.Hashtbl.find orig_kernel_functions x + with Not_found -> x); + get_original_fundec = + (fun x -> + try Cil_datatype.Varinfo.Hashtbl.find orig_fundecs x.svar + with Not_found -> x); + cinitinfo = (fun x -> { init = x.init }); + cblock = (fun x -> { x with battrs = x.battrs }); + cfunspec = (fun x -> { x with spec_behavior = x.spec_behavior}); + cfunbehavior = (fun x -> { x with b_name = x.b_name}); + ccode_annotation = + if fresh then Logic_const.refresh_code_annotation + else (fun x -> { x with annot_id = x.annot_id }); + cidentified_predicate = + if fresh then Logic_const.refresh_predicate + else (fun x -> { x with ip_id = x.ip_id }); + cidentified_term = + if fresh then Logic_const.refresh_identified_term + else (fun x -> { x with it_id = x.it_id}); + cexpr = + (fun x -> + let id = if fresh then Cil_const.Eid.next () else x.eid in { x with eid = id }); + is_copy_behavior = true; + is_fresh_behavior = fresh; + project = Some prj; + reset_behavior_varinfo = + (fun () -> + Cil_datatype.Varinfo.Hashtbl.clear varinfos; + Cil_datatype.Varinfo.Hashtbl.clear orig_varinfos); + reset_behavior_compinfo = + (fun () -> + Cil_datatype.Compinfo.Hashtbl.clear compinfos; + Cil_datatype.Compinfo.Hashtbl.clear orig_compinfos); + reset_behavior_enuminfo = + (fun () -> + Cil_datatype.Enuminfo.Hashtbl.clear enuminfos; + Cil_datatype.Enuminfo.Hashtbl.clear orig_enuminfos); + reset_behavior_enumitem = + (fun () -> + Cil_datatype.Enumitem.Hashtbl.clear enumitems; + Cil_datatype.Enumitem.Hashtbl.clear orig_enumitems); + reset_behavior_typeinfo = + (fun () -> + Cil_datatype.Typeinfo.Hashtbl.clear typeinfos; + Cil_datatype.Typeinfo.Hashtbl.clear orig_typeinfos); + reset_behavior_logic_info = + (fun () -> + Cil_datatype.Logic_info.Hashtbl.clear logic_infos; + Cil_datatype.Logic_info.Hashtbl.clear orig_logic_infos); + reset_behavior_logic_type_info = + (fun () -> + Cil_datatype.Logic_type_info.Hashtbl.clear logic_type_infos; + Cil_datatype.Logic_type_info.Hashtbl.clear orig_logic_type_infos); + reset_behavior_fieldinfo = + (fun () -> + Cil_datatype.Fieldinfo.Hashtbl.clear fieldinfos; + Cil_datatype.Fieldinfo.Hashtbl.clear orig_fieldinfos); + reset_behavior_model_info = + (fun () -> + Cil_datatype.Model_info.Hashtbl.clear model_infos; + Cil_datatype.Model_info.Hashtbl.clear orig_model_infos); + reset_behavior_stmt = + (fun () -> + Cil_datatype.Stmt.Hashtbl.clear stmts; + Cil_datatype.Stmt.Hashtbl.clear orig_stmts); + reset_logic_var = + (fun () -> + Cil_datatype.Logic_var.Hashtbl.clear logic_vars; + Cil_datatype.Logic_var.Hashtbl.clear orig_logic_vars); + reset_behavior_kernel_function = + (fun () -> + Cil_datatype.Kf.Hashtbl.clear kernel_functions; + Cil_datatype.Kf.Hashtbl.clear orig_kernel_functions); + reset_behavior_fundec = + (fun () -> + Cil_datatype.Varinfo.Hashtbl.clear fundecs; + Cil_datatype.Varinfo.Hashtbl.clear orig_fundecs); + memo_varinfo = temp_memo_varinfo; + memo_compinfo = temp_memo_compinfo; + memo_enuminfo = + (fun x -> + try Cil_datatype.Enuminfo.Hashtbl.find enuminfos x + with Not_found -> + let new_x = { x with ename = x.ename } in + Cil_datatype.Enuminfo.Hashtbl.add enuminfos x new_x; + Cil_datatype.Enuminfo.Hashtbl.add orig_enuminfos new_x x; + new_x); + memo_enumitem = + (fun x -> + try Cil_datatype.Enumitem.Hashtbl.find enumitems x + with Not_found -> + let new_x = { x with einame = x.einame } in + Cil_datatype.Enumitem.Hashtbl.add enumitems x new_x; + Cil_datatype.Enumitem.Hashtbl.add orig_enumitems new_x x; + new_x); + memo_typeinfo = + (fun x -> + try Cil_datatype.Typeinfo.Hashtbl.find typeinfos x + with Not_found -> + let new_x = { x with tname = x.tname } in + Cil_datatype.Typeinfo.Hashtbl.add typeinfos x new_x; + Cil_datatype.Typeinfo.Hashtbl.add orig_typeinfos new_x x; + new_x); + memo_logic_info = + (fun x -> + try Cil_datatype.Logic_info.Hashtbl.find logic_infos x + with Not_found -> + let new_v = temp_memo_logic_var x.l_var_info in + let new_x = { x with l_var_info = new_v } in + Cil_datatype.Logic_info.Hashtbl.add logic_infos x new_x; + Cil_datatype.Logic_info.Hashtbl.add orig_logic_infos new_x x; + new_x); + memo_logic_type_info = + (fun x -> + try Cil_datatype.Logic_type_info.Hashtbl.find logic_type_infos x + with Not_found -> + let new_x = { x with lt_name = x.lt_name } in + Cil_datatype.Logic_type_info.Hashtbl.add logic_type_infos x new_x; + Cil_datatype.Logic_type_info.Hashtbl.add + orig_logic_type_infos new_x x; + new_x); + memo_stmt = + (fun x -> + try Cil_datatype.Stmt.Hashtbl.find stmts x + with Not_found -> + let sid = if fresh then Cil_const.Sid.next () else x.sid in + let new_x = { x with sid = sid } in + Cil_datatype.Stmt.Hashtbl.add stmts x new_x; + Cil_datatype.Stmt.Hashtbl.add orig_stmts new_x x; + new_x); + memo_fieldinfo = + (fun x -> + try Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x + with Not_found -> + let _ = temp_memo_compinfo x.fcomp in + (* memo_compinfo fills the field correspondence table as well *) + let new_x = Cil_datatype.Fieldinfo.Hashtbl.find fieldinfos x in + Cil_datatype.Fieldinfo.Hashtbl.add fieldinfos x new_x; + Cil_datatype.Fieldinfo.Hashtbl.add orig_fieldinfos new_x x; + new_x); + memo_model_info = + (fun x -> + try Cil_datatype.Model_info.Hashtbl.find model_infos x + with Not_found -> + let new_x = { x with mi_name = x.mi_name } in + Cil_datatype.Model_info.Hashtbl.add model_infos x new_x; + Cil_datatype.Model_info.Hashtbl.add orig_model_infos new_x x; + new_x + ); + memo_logic_var = temp_memo_logic_var; + memo_kernel_function = temp_memo_kernel_function; + memo_fundec = temp_memo_fundec; + set_varinfo = temp_set_varinfo; + set_compinfo = temp_set_compinfo; + set_enuminfo = Cil_datatype.Enuminfo.Hashtbl.replace enuminfos; + set_enumitem = Cil_datatype.Enumitem.Hashtbl.replace enumitems; + set_typeinfo = Cil_datatype.Typeinfo.Hashtbl.replace typeinfos; + set_logic_info = Cil_datatype.Logic_info.Hashtbl.replace logic_infos; + set_logic_type_info = + Cil_datatype.Logic_type_info.Hashtbl.replace logic_type_infos; + set_stmt = Cil_datatype.Stmt.Hashtbl.replace stmts; + set_fieldinfo = Cil_datatype.Fieldinfo.Hashtbl.replace fieldinfos; + set_model_info = Cil_datatype.Model_info.Hashtbl.replace model_infos; + set_logic_var = temp_set_logic_var; + set_kernel_function = temp_set_kernel_function; + set_fundec = temp_set_fundec; + set_orig_varinfo = temp_set_orig_varinfo; + set_orig_compinfo = temp_set_orig_compinfo; + set_orig_enuminfo = Cil_datatype.Enuminfo.Hashtbl.replace orig_enuminfos; + set_orig_enumitem = Cil_datatype.Enumitem.Hashtbl.replace orig_enumitems; + set_orig_typeinfo = Cil_datatype.Typeinfo.Hashtbl.replace orig_typeinfos; + set_orig_logic_info = + Cil_datatype.Logic_info.Hashtbl.replace orig_logic_infos; + set_orig_logic_type_info = + Cil_datatype.Logic_type_info.Hashtbl.replace orig_logic_type_infos; + set_orig_stmt = Cil_datatype.Stmt.Hashtbl.replace orig_stmts; + set_orig_fieldinfo = + Cil_datatype.Fieldinfo.Hashtbl.replace orig_fieldinfos; + set_orig_model_info = + Cil_datatype.Model_info.Hashtbl.replace orig_model_infos; + set_orig_logic_var = temp_set_orig_logic_var; + set_orig_kernel_function = temp_set_orig_kernel_function; + set_orig_fundec = temp_set_orig_fundec; + + unset_varinfo = temp_unset_varinfo; + unset_compinfo = temp_unset_compinfo; + unset_enuminfo = Cil_datatype.Enuminfo.Hashtbl.remove enuminfos; + unset_enumitem = Cil_datatype.Enumitem.Hashtbl.remove enumitems; + unset_typeinfo = Cil_datatype.Typeinfo.Hashtbl.remove typeinfos; + unset_logic_info = Cil_datatype.Logic_info.Hashtbl.remove logic_infos; + unset_logic_type_info = + Cil_datatype.Logic_type_info.Hashtbl.remove logic_type_infos; + unset_stmt = Cil_datatype.Stmt.Hashtbl.remove stmts; + unset_fieldinfo = Cil_datatype.Fieldinfo.Hashtbl.remove fieldinfos; + unset_model_info = Cil_datatype.Model_info.Hashtbl.remove model_infos; + unset_logic_var = temp_unset_logic_var; + unset_kernel_function = temp_unset_kernel_function; + unset_fundec = temp_unset_fundec; + + unset_orig_varinfo = temp_unset_orig_varinfo; + unset_orig_compinfo = temp_unset_orig_compinfo; + unset_orig_enuminfo = Cil_datatype.Enuminfo.Hashtbl.remove orig_enuminfos; + unset_orig_enumitem = Cil_datatype.Enumitem.Hashtbl.remove orig_enumitems; + unset_orig_typeinfo = Cil_datatype.Typeinfo.Hashtbl.remove orig_typeinfos; + unset_orig_logic_info = + Cil_datatype.Logic_info.Hashtbl.remove orig_logic_infos; + unset_orig_logic_type_info = + Cil_datatype.Logic_type_info.Hashtbl.remove orig_logic_type_infos; + unset_orig_stmt = Cil_datatype.Stmt.Hashtbl.remove orig_stmts; + unset_orig_fieldinfo = + Cil_datatype.Fieldinfo.Hashtbl.remove orig_fieldinfos; + unset_orig_model_info = + Cil_datatype.Model_info.Hashtbl.remove orig_model_infos; + unset_orig_logic_var = temp_unset_orig_logic_var; + unset_orig_kernel_function = temp_unset_orig_kernel_function; + unset_orig_fundec = temp_unset_orig_fundec; + + iter_visitor_varinfo = + (fun f -> Cil_datatype.Varinfo.Hashtbl.iter f varinfos); + iter_visitor_compinfo = + (fun f -> Cil_datatype.Compinfo.Hashtbl.iter f compinfos); + iter_visitor_enuminfo = + (fun f -> Cil_datatype.Enuminfo.Hashtbl.iter f enuminfos); + iter_visitor_enumitem = + (fun f -> Cil_datatype.Enumitem.Hashtbl.iter f enumitems); + iter_visitor_typeinfo = + (fun f -> Cil_datatype.Typeinfo.Hashtbl.iter f typeinfos); + iter_visitor_stmt = + (fun f -> Cil_datatype.Stmt.Hashtbl.iter f stmts); + iter_visitor_logic_info = + (fun f -> Cil_datatype.Logic_info.Hashtbl.iter f logic_infos); + iter_visitor_logic_type_info = + (fun f -> Cil_datatype.Logic_type_info.Hashtbl.iter f logic_type_infos); + iter_visitor_fieldinfo = + (fun f -> Cil_datatype.Fieldinfo.Hashtbl.iter f fieldinfos); + iter_visitor_model_info = + (fun f -> Cil_datatype.Model_info.Hashtbl.iter f model_infos); + iter_visitor_logic_var = + (fun f -> Cil_datatype.Logic_var.Hashtbl.iter f logic_vars); + iter_visitor_kernel_function = + (fun f -> Cil_datatype.Kf.Hashtbl.iter f kernel_functions); + iter_visitor_fundec = + (fun f -> + let f _ new_fundec = + let old_fundec = + Cil_datatype.Varinfo.Hashtbl.find orig_fundecs new_fundec.svar + in + f old_fundec new_fundec + in + Cil_datatype.Varinfo.Hashtbl.iter f fundecs); + fold_visitor_varinfo = + (fun f i -> Cil_datatype.Varinfo.Hashtbl.fold f varinfos i); + fold_visitor_compinfo = + (fun f i -> Cil_datatype.Compinfo.Hashtbl.fold f compinfos i); + fold_visitor_enuminfo = + (fun f i -> Cil_datatype.Enuminfo.Hashtbl.fold f enuminfos i); + fold_visitor_enumitem = + (fun f i -> Cil_datatype.Enumitem.Hashtbl.fold f enumitems i); + fold_visitor_typeinfo = + (fun f i -> Cil_datatype.Typeinfo.Hashtbl.fold f typeinfos i); + fold_visitor_stmt = + (fun f i -> Cil_datatype.Stmt.Hashtbl.fold f stmts i); + fold_visitor_logic_info = + (fun f i -> Cil_datatype.Logic_info.Hashtbl.fold f logic_infos i); + fold_visitor_logic_type_info = + (fun f i -> + Cil_datatype.Logic_type_info.Hashtbl.fold f logic_type_infos i); + fold_visitor_fieldinfo = + (fun f i -> Cil_datatype.Fieldinfo.Hashtbl.fold f fieldinfos i); + fold_visitor_model_info = + (fun f i -> Cil_datatype.Model_info.Hashtbl.fold f model_infos i); + fold_visitor_logic_var = + (fun f i -> Cil_datatype.Logic_var.Hashtbl.fold f logic_vars i); + fold_visitor_kernel_function = + (fun f i -> + Cil_datatype.Kf.Hashtbl.fold f kernel_functions i); + fold_visitor_fundec = + (fun f i -> + let f _ new_fundec acc = + let old_fundec = + Cil_datatype.Varinfo.Hashtbl.find orig_fundecs new_fundec.svar + in + f old_fundec new_fundec acc + in + Cil_datatype.Varinfo.Hashtbl.fold f fundecs i); + } + +let copy = copy_visit_gen false +let refresh = copy_visit_gen true + +let is_copy b = b.is_copy_behavior +let is_fresh b = b.is_fresh_behavior + +let get_project b = b.project + +let ccode_annotation b = b.ccode_annotation +let cexpr b = b.cexpr +let cidentified_predicate b = b.cidentified_predicate +let cidentified_term b = b.cidentified_term +let cfunbehavior b = b.cfunbehavior +let cfunspec b = b.cfunspec +let cblock b = b.cblock +let cinitinfo b = b.cinitinfo +let cfile b = b.cfile + +module Memo = struct + let varinfo b = b.memo_varinfo + let compinfo b = b.memo_compinfo + let fieldinfo b = b.memo_fieldinfo + let model_info b = b.memo_model_info + let enuminfo b = b.memo_enuminfo + let enumitem b = b.memo_enumitem + let stmt b = b.memo_stmt + let typeinfo b = b.memo_typeinfo + let logic_info b = b.memo_logic_info + let logic_type_info b = b.memo_logic_type_info + let logic_var b = b.memo_logic_var + let kernel_function b = b.memo_kernel_function + let fundec b = b.memo_fundec +end + +module Reset = struct + let varinfo b = b.reset_behavior_varinfo () + let compinfo b = b.reset_behavior_compinfo () + let enuminfo b = b.reset_behavior_enuminfo () + let enumitem b = b.reset_behavior_enumitem () + let typeinfo b = b.reset_behavior_typeinfo () + let logic_info b = b.reset_behavior_logic_info () + let logic_type_info b = b.reset_behavior_logic_type_info () + let fieldinfo b = b.reset_behavior_fieldinfo () + let model_info b = b.reset_behavior_model_info () + let stmt b = b.reset_behavior_stmt () + let logic_var b = b.reset_logic_var () + let kernel_function b = b.reset_behavior_kernel_function () + let fundec b = b.reset_behavior_fundec () +end + +module type Get = sig + val varinfo: t -> varinfo -> varinfo + val compinfo: t -> compinfo -> compinfo + val enuminfo: t -> enuminfo -> enuminfo + val enumitem: t -> enumitem -> enumitem + val typeinfo: t -> typeinfo -> typeinfo + val stmt: t -> stmt -> stmt + val logic_info: t -> logic_info -> logic_info + val logic_type_info: t -> logic_type_info -> logic_type_info + val fieldinfo: t -> fieldinfo -> fieldinfo + val model_info: t -> model_info -> model_info + val logic_var: t -> logic_var -> logic_var + val kernel_function: t -> kernel_function -> kernel_function + val fundec: t -> fundec -> fundec +end + +module Get = struct + let varinfo b = b.get_varinfo + let compinfo b = b.get_compinfo + let fieldinfo b = b.get_fieldinfo + let model_info b = b.get_model_info + let enuminfo b = b.get_enuminfo + let enumitem b = b.get_enumitem + let stmt b = b.get_stmt + let typeinfo b = b.get_typeinfo + let logic_info b = b.get_logic_info + let logic_type_info b = b.get_logic_type_info + let logic_var b = b.get_logic_var + let kernel_function b = b.get_kernel_function + let fundec b = b.get_fundec +end + +module Get_orig = struct + let varinfo b = b.get_original_varinfo + let compinfo b = b.get_original_compinfo + let fieldinfo b = b.get_original_fieldinfo + let model_info b = b.get_original_model_info + let enuminfo b = b.get_original_enuminfo + let enumitem b = b.get_original_enumitem + let stmt b = b.get_original_stmt + let typeinfo b = b.get_original_typeinfo + let logic_info b = b.get_original_logic_info + let logic_type_info b = b.get_original_logic_type_info + let logic_var b = b.get_original_logic_var + let kernel_function b = b.get_original_kernel_function + let fundec b = b.get_original_fundec +end + +module type Set = sig + val varinfo: t -> varinfo -> varinfo -> unit + val compinfo: t -> compinfo -> compinfo -> unit + val enuminfo: t -> enuminfo -> enuminfo -> unit + val enumitem: t -> enumitem -> enumitem -> unit + val typeinfo: t -> typeinfo -> typeinfo -> unit + val stmt: t -> stmt -> stmt -> unit + + val logic_info: t -> logic_info -> logic_info -> unit + val logic_type_info: + t -> logic_type_info -> logic_type_info -> unit + val fieldinfo: t -> fieldinfo -> fieldinfo -> unit + val model_info: t -> model_info -> model_info -> unit + val logic_var: t -> logic_var -> logic_var -> unit + val kernel_function: + t -> kernel_function -> kernel_function -> unit + val fundec: t -> fundec -> fundec -> unit +end + +module Set = struct + let varinfo b = b.set_varinfo + let compinfo b = b.set_compinfo + let fieldinfo b = b.set_fieldinfo + let model_info b = b.set_model_info + let enuminfo b = b.set_enuminfo + let enumitem b = b.set_enumitem + let stmt b = b.set_stmt + let typeinfo b = b.set_typeinfo + let logic_info b = b.set_logic_info + let logic_type_info b = b.set_logic_type_info + let logic_var b = b.set_logic_var + let kernel_function b = b.set_kernel_function + let fundec b = b.set_fundec +end + +module Set_orig = struct + let varinfo b = b.set_orig_varinfo + let compinfo b = b.set_orig_compinfo + let fieldinfo b = b.set_orig_fieldinfo + let model_info b = b.set_model_info + let enuminfo b = b.set_orig_enuminfo + let enumitem b = b.set_orig_enumitem + let stmt b = b.set_orig_stmt + let typeinfo b = b.set_orig_typeinfo + let logic_info b = b.set_orig_logic_info + let logic_type_info b = b.set_orig_logic_type_info + let logic_var b = b.set_orig_logic_var + let kernel_function b = b.set_orig_kernel_function + let fundec b = b.set_orig_fundec +end + +module type Unset = sig + val varinfo: t -> varinfo -> unit + val compinfo: t -> compinfo -> unit + val enuminfo: t -> enuminfo -> unit + val enumitem: t -> enumitem -> unit + val typeinfo: t -> typeinfo -> unit + val stmt: t -> stmt -> unit + + val logic_info: t -> logic_info -> unit + val logic_type_info: t -> logic_type_info -> unit + val fieldinfo: t -> fieldinfo -> unit + val model_info: t -> model_info -> unit + val logic_var: t -> logic_var -> unit + val kernel_function: t -> kernel_function -> unit + val fundec: t -> fundec -> unit +end + +module Unset = struct + let varinfo b = b.unset_varinfo + let compinfo b = b.unset_compinfo + let fieldinfo b = b.unset_fieldinfo + let model_info b = b.unset_model_info + let enuminfo b = b.unset_enuminfo + let enumitem b = b.unset_enumitem + let stmt b = b.unset_stmt + let typeinfo b = b.unset_typeinfo + let logic_info b = b.unset_logic_info + let logic_type_info b = b.unset_logic_type_info + let logic_var b = b.unset_logic_var + let kernel_function b = b.unset_kernel_function + let fundec b = b.unset_fundec +end + +module Unset_orig = struct + let varinfo b = b.unset_orig_varinfo + let compinfo b = b.unset_orig_compinfo + let fieldinfo b = b.unset_orig_fieldinfo + let model_info b = b.unset_model_info + let enuminfo b = b.unset_orig_enuminfo + let enumitem b = b.unset_orig_enumitem + let stmt b = b.unset_orig_stmt + let typeinfo b = b.unset_orig_typeinfo + let logic_info b = b.unset_orig_logic_info + let logic_type_info b = b.unset_orig_logic_type_info + let logic_var b = b.unset_orig_logic_var + let kernel_function b = b.unset_orig_kernel_function + let fundec b = b.unset_orig_fundec +end + +module Iter = struct + let varinfo b = b.iter_visitor_varinfo + let compinfo b = b.iter_visitor_compinfo + let enuminfo b = b.iter_visitor_enuminfo + let enumitem b = b.iter_visitor_enumitem + let typeinfo b = b.iter_visitor_typeinfo + let stmt b = b.iter_visitor_stmt + let logic_info b = b.iter_visitor_logic_info + let logic_type_info b = b.iter_visitor_logic_type_info + let fieldinfo b = b.iter_visitor_fieldinfo + let model_info b = b.iter_visitor_model_info + let logic_var b = b.iter_visitor_logic_var + let kernel_function b = b.iter_visitor_kernel_function + let fundec b = b.iter_visitor_fundec +end + +module Fold = struct + let varinfo b = b.fold_visitor_varinfo + let compinfo b = b.fold_visitor_compinfo + let enuminfo b = b.fold_visitor_enuminfo + let enumitem b = b.fold_visitor_enumitem + let typeinfo b = b.fold_visitor_typeinfo + let stmt b = b.fold_visitor_stmt + let logic_info b = b.fold_visitor_logic_info + let logic_type_info b = b.fold_visitor_logic_type_info + let fieldinfo b = b.fold_visitor_fieldinfo + let model_info b = b.fold_visitor_model_info + let logic_var b = b.fold_visitor_logic_var + let kernel_function b = b.fold_visitor_kernel_function + let fundec b = b.fold_visitor_fundec +end diff --git a/src/kernel_services/visitors/visitor_behavior.mli b/src/kernel_services/visitors/visitor_behavior.mli new file mode 100644 index 0000000000000000000000000000000000000000..f448e0a69c9840d598a1f8242925b8476507ab52 --- /dev/null +++ b/src/kernel_services/visitors/visitor_behavior.mli @@ -0,0 +1,326 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* INRIA (Institut National de Recherche en Informatique et en *) +(* Automatique) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +(** Operations on visitor behaviors. + @since Potassium-19.0+dev. +*) + +open Cil_types + +type t +(** How the visitor should behave in front of mutable fields: in + place modification or copy of the structure. This type is abstract. + Use one of the two values below in your classes. + @plugin development guide *) + +val inplace: unit -> t +(** In-place modification. Behavior of the original cil visitor. + @plugin development guide *) + +val copy: Project.t -> t +(** Makes fresh copies of the mutable structures. + - preserves sharing for varinfo. + - makes fresh copy of varinfo only for declarations. Variables that are + only used in the visited AST are thus still shared with the original + AST. This allows for instance to copy a function with its + formals and local variables, and to keep the references to other + globals in the function's body. + @plugin development guide *) + +val refresh: Project.t -> t +(** Makes fresh copies of the mutable structures and provides fresh id + for the structures that have ids. Note that as for {!copy_visit}, only + varinfo that are declared in the scope of the visit will be copied and + provided with a new id. +*) + +(** true iff the behavior provides fresh id for copied structs with id. + Always [false] for an inplace visitor. +*) +val is_fresh: t -> bool + +(** true iff the behavior is a copy behavior. *) +val is_copy: t -> bool + +val get_project: t -> Project.t option + +(** Reset operations on behaviors, allows to reset the tables associated to a given + kind of AST elements. If you use fresh instances of visitor for each round of + transformation, you should not need this module. In place modifications + do not need this at all. + + [Reset.ast_element vis] resets the tables associated to the considered type of + AST elements in [vis]. For example for {!Cil_types.varinfo}: [Reset.varinfo vis]. + + @since Potassium-19.0+dev + @plugin development guide +*) +module Reset: sig + val varinfo: t -> unit + val compinfo: t -> unit + val enuminfo: t -> unit + val enumitem: t -> unit + val typeinfo: t -> unit + val stmt: t -> unit + val logic_info: t -> unit + val logic_type_info: t -> unit + val fieldinfo: t -> unit + val model_info: t -> unit + val logic_var: t -> unit + val kernel_function: t -> unit + val fundec: t -> unit +end + +module type Get = sig + val varinfo: t -> varinfo -> varinfo + val compinfo: t -> compinfo -> compinfo + val enuminfo: t -> enuminfo -> enuminfo + val enumitem: t -> enumitem -> enumitem + val typeinfo: t -> typeinfo -> typeinfo + val stmt: t -> stmt -> stmt + val logic_info: t -> logic_info -> logic_info + val logic_type_info: t -> logic_type_info -> logic_type_info + val fieldinfo: t -> fieldinfo -> fieldinfo + val model_info: t -> model_info -> model_info + val logic_var: t -> logic_var -> logic_var + val kernel_function: t -> kernel_function -> kernel_function + val fundec: t -> fundec -> fundec +end + +(** Get operations on behaviors, allows to get the representative of an + AST element in the current state of the visitor. + + [Get.ast_element vis e] with [e] of type [ast_element] gets the + representative of [e] in [vis]. For example for {!Cil_types.varinfo}: + [Get.varinfo vis vi]. + + @since Potassium-19.0+dev + @plugin development guide +*) +module Get: Get + +(** Get operations on behaviors, allows to get the original representative of + an element of the {b new} AST in the curent state of the visitor. + + [Get_orig.ast_element vis new_e] with [new_e] of type [ast_element] gets the + original representative of [new_e] in [vis]. For example for + {!Cil_types.varinfo}: [Get_orig.varinfo vis new_vi]. + + @since Potassium-19.0+dev + @plugin development guide +*) +module Get_orig: Get + +(** Memo operations on behaviors, allows to get a binding in the new project + for the given AST element, creating one if it does not already exists. + + [Memo.ast_element vis e] with [e] of type [ast_element] tries to find a + binding to a [e] in the new project created using [vis] in the current + state, if it does not exist this binding is created. For example for + {!Cil_types.varinfo}: [Memo.varinfo vis vi]. + + @since Potassium-19.0+dev + @plugin development guide +*) +module Memo: Get + +module type Set = sig + val varinfo: t -> varinfo -> varinfo -> unit + val compinfo: t -> compinfo -> compinfo -> unit + val enuminfo: t -> enuminfo -> enuminfo -> unit + val enumitem: t -> enumitem -> enumitem -> unit + val typeinfo: t -> typeinfo -> typeinfo -> unit + val stmt: t -> stmt -> stmt -> unit + + val logic_info: t -> logic_info -> logic_info -> unit + val logic_type_info: + t -> logic_type_info -> logic_type_info -> unit + val fieldinfo: t -> fieldinfo -> fieldinfo -> unit + val model_info: t -> model_info -> model_info -> unit + val logic_var: t -> logic_var -> logic_var -> unit + val kernel_function: + t -> kernel_function -> kernel_function -> unit + val fundec: t -> fundec -> fundec -> unit +end + +(** Set operations on behaviors, allows to change the representative of a + given AST element in the current state of the visitor. Use with care + (i.e. makes sure that the old one is not referenced anywhere in the + AST, or sharing will be lost). + + [Set.ast_element vis e s] with [e] and [s] of type [ast_element] changes + the representative of [e] to [s] in [vis]. For example, for + {!Cil_types.varinfo}: [Set.varinfo vis vi new_representative]. + + @since Potassium-19.0+dev + @plugin development guide +*) +module Set: Set + +(** Set operations on behaviors related to original representatives, allows to + change the reference of an element of the {b new} AST in the current state + of the visitor. Use with care. + + [Set.ast_element vis e s] with [e] and [s] of type [ast_element] changes + the original representative of [e] to [s] in [vis]. For example, for + {!Cil_types.varinfo}: [Set_orig.varinfo vis vi new_original_repr]. + + @since Potassium-19.0+dev +*) +module Set_orig: Set + +module type Unset = sig + val varinfo: t -> varinfo -> unit + val compinfo: t -> compinfo -> unit + val enuminfo: t -> enuminfo -> unit + val enumitem: t -> enumitem -> unit + val typeinfo: t -> typeinfo -> unit + val stmt: t -> stmt -> unit + + val logic_info: t -> logic_info -> unit + val logic_type_info: t -> logic_type_info -> unit + val fieldinfo: t -> fieldinfo -> unit + val model_info: t -> model_info -> unit + val logic_var: t -> logic_var -> unit + val kernel_function: t -> kernel_function -> unit + val fundec: t -> fundec -> unit +end + + +(** Operations to remove the entry associated to a given AST element in the + current state of the visitor. Use with care (i.e. make sure that you will + never visit again this element in the same visiting context). + + [Unset.ast_element vis e] with [e] of type [ast_element] removes the + representative of [e] in the [ast_element] table of [vis]. For example, + for {!Cil_types.varinfo}: [Unset.varinfo vis vi]. + + @since Potassium-19.0+dev +*) +module Unset: Unset + +(** Operations to remove the entry associated to a given element of the {b new} + AST in the current state of the visitor. Use with care. + + [Unset_orig.ast_element vis e] with [e] of type [ast_element] removes the + original representative of [e] in the [ast_element] table of [vis]. For + example, for {!Cil_types.varinfo}: [Unset_orig.varinfo vis vi]. + + @since Potassium-19.0+dev +*) +module Unset_orig: Unset + +(** Iter operations on the table of a given type of AST elements. + + [Iter.ast_element vis f], iterates [f] over each pair of [ast_element] + registered in [vis]. The [ast_element] in the old AST is presented to [f] + first (that is, [f] looks like: [let f old_e new_e = ...]. For example for + {!Cil_types.varinfo}: [Iter.varinfo vis (fun old_vi new_vi -> ())]. + + @since Potassium-19.0+dev +*) +module Iter: sig + val varinfo: + t -> (varinfo -> varinfo -> unit) -> unit + val compinfo: + t -> (compinfo -> compinfo -> unit) -> unit + val enuminfo: + t -> (enuminfo -> enuminfo -> unit) -> unit + val enumitem: + t -> (enumitem -> enumitem -> unit) -> unit + val typeinfo: + t -> (typeinfo -> typeinfo -> unit) -> unit + val stmt: + t -> (stmt -> stmt -> unit) -> unit + val logic_info: + t -> (logic_info -> logic_info -> unit) -> unit + val logic_type_info: + t -> (logic_type_info -> logic_type_info -> unit) -> unit + val fieldinfo: + t -> (fieldinfo -> fieldinfo -> unit) -> unit + val model_info: + t -> (model_info -> model_info -> unit) -> unit + val logic_var: + t -> (logic_var -> logic_var -> unit) -> unit + val kernel_function: + t -> (kernel_function -> kernel_function -> unit) -> unit + val fundec: + t -> (fundec -> fundec -> unit) -> unit +end + +(** Fold operations on table of a given type of AST elements. + + [Fold.ast_element vis f], folds [f] over each pair of [ast_element] + registered in [vis]. The [ast_element] in the old AST is presented to [f] + first (that is, [f] looks like: [let f old_e new_e acc = ...]. For example + for {!Cil_types.varinfo}: + [Fold.varinfo vis (fun old_vi new_vi acc -> ... )]. + + @since Potassium-19.0+dev +*) +module Fold: sig + val varinfo: + t -> (varinfo -> varinfo -> 'a -> 'a) -> 'a -> 'a + val compinfo: + t -> (compinfo -> compinfo -> 'a -> 'a) -> 'a -> 'a + val enuminfo: + t -> (enuminfo -> enuminfo -> 'a -> 'a) -> 'a -> 'a + val enumitem: + t -> (enumitem -> enumitem -> 'a -> 'a) -> 'a -> 'a + val typeinfo: + t -> (typeinfo -> typeinfo -> 'a -> 'a) -> 'a -> 'a + val stmt: + t -> (stmt -> stmt -> 'a -> 'a) -> 'a -> 'a + val logic_info: + t -> (logic_info -> logic_info -> 'a -> 'a) -> 'a -> 'a + val logic_type_info: + t -> + (logic_type_info -> logic_type_info -> 'a -> 'a) -> 'a -> 'a + val fieldinfo: + t -> (fieldinfo -> fieldinfo -> 'a -> 'a) -> 'a -> 'a + val model_info: + t -> (model_info -> model_info -> 'a -> 'a) -> 'a -> 'a + val logic_var: + t -> (logic_var -> logic_var -> 'a -> 'a) -> 'a -> 'a + val kernel_function: + t -> + (kernel_function -> kernel_function -> 'a -> 'a) -> 'a -> 'a + val fundec: + t -> (fundec -> fundec -> 'a -> 'a) -> 'a -> 'a +end + + +(**/**) + +(** For INTERNAL USE only *) + +val cfile: t -> file -> file +val cinitinfo: t -> initinfo -> initinfo +val cblock: t -> block -> block +val cfunspec: t -> funspec -> funspec +val cfunbehavior: t -> funbehavior -> funbehavior +val cidentified_term: t -> identified_term -> identified_term +val cidentified_predicate: t -> identified_predicate -> identified_predicate +val cexpr: t -> exp -> exp +val ccode_annotation: t -> code_annotation -> code_annotation diff --git a/src/plugins/aorai/aorai_visitors.ml b/src/plugins/aorai/aorai_visitors.ml index 68571210062b0840fed735fc4ff2666354155d20..165990df1ce1bf35fe8b81f022bcd9820cd24d98 100644 --- a/src/plugins/aorai/aorai_visitors.ml +++ b/src/plugins/aorai/aorai_visitors.ml @@ -978,7 +978,7 @@ object(self) Cil.mkStmtOneInstr (Set((Var vi_init,NoOffset), Cil.zero ~loc, loc)) in - stmt_varset.sid<-(Cil.Sid.next ()); + stmt_varset.sid<-(Cil_const.Sid.next ()); stmt_varset.ghost<-true; begin (* Function adapted from the cil printer *) diff --git a/src/plugins/constant_propagation/api.ml b/src/plugins/constant_propagation/api.ml index 58c9aa199a689ab05b50958687f1d4504cd33ed1..88a83bc845c27adf32855a8f2ed694d73200001a 100644 --- a/src/plugins/constant_propagation/api.ml +++ b/src/plugins/constant_propagation/api.ml @@ -74,7 +74,7 @@ class propagate project fnames ~cast_intro = object(self) known_globals <- Varinfo.Set.add vi known_globals; if Cil.isFunctionType vi.vtype then begin let kf = Globals.Functions.get vi in - let new_kf = Cil.memo_kernel_function self#behavior kf in + let new_kf = Visitor_behavior.Memo.kernel_function self#behavior kf in Queue.add (fun () -> Globals.Functions.register new_kf) self#get_filling_actions; end diff --git a/src/plugins/scope/datascope.ml b/src/plugins/scope/datascope.ml index 007449cd839883d7bc0e23c04090445f2b2be633..2428d248fd935bbd304d08b1ff0d3a298e7753da 100644 --- a/src/plugins/scope/datascope.ml +++ b/src/plugins/scope/datascope.ml @@ -571,7 +571,8 @@ class check_annot_visitor = object(self) method! vcode_annot annot = let kf = Extlib.the self#current_kf in let stmt = - Cil.get_original_stmt self#behavior (Extlib.the self#current_stmt) + Visitor_behavior.Get_orig.stmt + self#behavior (Extlib.the self#current_stmt) in begin match annot.annot_content with | AAssert _ -> diff --git a/src/plugins/sparecode/globs.ml b/src/plugins/sparecode/globs.ml index eb84a71c48abcc51a8426777bde0d3247c18dfec..6021439c1bb1872bed135b5659777adfc9ccf1b1 100644 --- a/src/plugins/sparecode/globs.ml +++ b/src/plugins/sparecode/globs.ml @@ -110,7 +110,7 @@ end class filter_visitor prj = object - inherit Visitor.generic_frama_c_visitor (Cil.copy_visit prj) + inherit Visitor.generic_frama_c_visitor (Visitor_behavior.copy prj) method! vglob_aux g = match g with diff --git a/src/plugins/wp/normAtLabels.ml b/src/plugins/wp/normAtLabels.ml index c876927da3c546f5a455079e05aba5710743e281..8a01575729702dc47de5c17c51f41cf9f03c8f4f 100644 --- a/src/plugins/wp/normAtLabels.ml +++ b/src/plugins/wp/normAtLabels.ml @@ -33,7 +33,8 @@ type label_mapping = Cil_types.logic_label -> Clabels.c_label * *) class norm_at (mapping : label_mapping) = object(self) - inherit Visitor.generic_frama_c_visitor (Cil.copy_visit (Project.current ())) + inherit Visitor.generic_frama_c_visitor + (Visitor_behavior.copy (Project.current ())) val mutable current_label = None diff --git a/tests/misc/bug_0209.ml b/tests/misc/bug_0209.ml index 37134ef7eee872aae616f6f82f9faefc609b55ab..b46478f7925e914d25506a3200d3d9e87b55885f 100644 --- a/tests/misc/bug_0209.ml +++ b/tests/misc/bug_0209.ml @@ -3,7 +3,8 @@ let main () = Logic_env.Builtins.apply *) ignore (File.create_project_from_visitor "foo" - (fun p -> new Visitor.generic_frama_c_visitor (Cil.copy_visit p))); + (fun p -> + new Visitor.generic_frama_c_visitor (Visitor_behavior.copy p))); let p = Project.create "bar" in (* Computing the AST first calls File.cil_init, than calls Logic_env.Builtins.apply. This second call raises an exception because diff --git a/tests/spec/Extend.ml b/tests/spec/Extend.ml index 980bcae57360b3ee4084f357dec73b8539d1f77d..eeb9585d6abde841f316f8a96dac43e883765f1a 100644 --- a/tests/spec/Extend.ml +++ b/tests/spec/Extend.ml @@ -50,7 +50,7 @@ let visit_bar vis ext = | Ext_id idx -> let l = Bar_table.find idx in let l' = Cil.mapNoCopy (Cil.visitCilPredicate vis) l in - if Cil.is_copy_behavior vis#behavior then begin + if Visitor_behavior.is_copy vis#behavior then begin let idx' = Count.next () in Queue.add (fun () -> Bar_table.add idx' l') vis#get_filling_actions; Cil.ChangeTo(Ext_id idx') diff --git a/tests/spec/property_test.ml b/tests/spec/property_test.ml index 1fef091214845c4be83ef7b5bffac13e3ff84d95..443e8cefd62dc590c13935476210378f744f6037 100644 --- a/tests/spec/property_test.ml +++ b/tests/spec/property_test.ml @@ -20,7 +20,7 @@ class visit prj = From [ Logic_const.new_identified_term (Logic_const.tvar x); Logic_const.new_identified_term (Logic_const.tvar c)] ]; - let nkf = Cil.get_kernel_function self#behavior kf in + let nkf = Visitor_behavior.Get.kernel_function self#behavior kf in let keep_empty = true in let post b = Queue.add diff --git a/tests/syntax/Refresh_visitor.ml b/tests/syntax/Refresh_visitor.ml index 850219bceb5a5a5aa51e785b951026d946af2f89..9a82d0fd6b4635681d12e70869a6769a7fa6283e 100644 --- a/tests/syntax/Refresh_visitor.ml +++ b/tests/syntax/Refresh_visitor.ml @@ -1,5 +1,5 @@ open Cil_types -open Cil +open Visitor_behavior let category = Kernel.register_category "refresh-test" @@ -31,7 +31,7 @@ let main () = File.init_project_from_visitor p vis; Cil_datatype.( let orig_id, copy_id, shared_id = - CheckVarinfo.check "varinfo" fold_visitor_varinfo vis#behavior + CheckVarinfo.check "varinfo" Fold.varinfo vis#behavior in if Kernel.is_debug_key_enabled category then begin Varinfo.Set.iter @@ -47,13 +47,13 @@ let main () = shared_id; end; let _ = - CheckCompinfo.check "compinfo" fold_visitor_compinfo vis#behavior + CheckCompinfo.check "compinfo" Fold.compinfo vis#behavior in let _ = - CheckStmt.check "stmt" fold_visitor_stmt vis#behavior; + CheckStmt.check "stmt" Fold.stmt vis#behavior; in let orig_id, copy_id, shared_id = - CheckLogic_var.check "logic var" fold_visitor_logic_var vis#behavior + CheckLogic_var.check "logic var" Fold.logic_var vis#behavior in if Kernel.is_debug_key_enabled category then begin Logic_var.Set.iter diff --git a/tests/syntax/copy_visitor_bts_1073.ml b/tests/syntax/copy_visitor_bts_1073.ml index 52073e68ac26990a41d8d51031ff529fe52d0675..a8bf07b17d614fc3f967f5aebdc594039b47403d 100644 --- a/tests/syntax/copy_visitor_bts_1073.ml +++ b/tests/syntax/copy_visitor_bts_1073.ml @@ -11,11 +11,11 @@ object(self) let f1 = Visitor.visitFramacFunction (self:>Visitor.frama_c_visitor) f in let v2 = Cil.copyVarinfo f.svar (f.svar.vname ^ "1") in - let orig = Cil.get_original_varinfo self#behavior f.svar in - Cil.set_varinfo self#behavior orig v2; - Cil.set_orig_varinfo self#behavior v2 orig; - Cil.reset_behavior_fundec self#behavior; - Cil.reset_behavior_stmt self#behavior; + let orig = Visitor_behavior.Get_orig.varinfo self#behavior f.svar in + Visitor_behavior.Set.varinfo self#behavior orig v2; + Visitor_behavior.Set_orig.varinfo self#behavior v2 orig; + Visitor_behavior.Reset.fundec self#behavior; + Visitor_behavior.Reset.stmt self#behavior; let f2 = Visitor.visitFramacFunction (self:>Visitor.frama_c_visitor) f in f2.svar <- v2; diff --git a/tests/syntax/transient_block.ml b/tests/syntax/transient_block.ml index 0bf3ce8e4aa34403c82d326a1954c14eb805e4e7..0938b72d74627597f86fd7fe7c6070c363e36bac 100644 --- a/tests/syntax/transient_block.ml +++ b/tests/syntax/transient_block.ml @@ -9,7 +9,8 @@ class vis prj = object(self) let s1 = Cil.mkStmtOneInstr ~valid_sid:true instr in let b = Cil.mkBlock [s1] in if create then begin - let f = Cil.get_fundec self#behavior (Extlib.the self#current_func) in + let f = Visitor_behavior.Get.fundec + self#behavior (Extlib.the self#current_func) in let y = Cil.makeLocalVar f ~scope:b "y" (TInt(IInt,[])) in my_var <- Some y; let loc = Cil_datatype.Location.unknown in @@ -31,7 +32,8 @@ class vis prj = object(self) with Log.AbortFatal _ -> Kernel.feedback "transient_block fatal error on %a as expected" Printer.pp_instr instr; - let f = Cil.get_fundec self#behavior (Extlib.the self#current_func) in + let f = Visitor_behavior.Get.fundec + self#behavior (Extlib.the self#current_func) in let y = Extlib.the my_var in f.slocals <- List.filter