diff options
Diffstat (limited to 'src/spec_analysis.ml')
| -rw-r--r-- | src/spec_analysis.ml | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/spec_analysis.ml b/src/spec_analysis.ml index fd43de16..c858754e 100644 --- a/src/spec_analysis.ml +++ b/src/spec_analysis.ml @@ -447,15 +447,26 @@ let rec fv_of_scattered consider_var consider_scatter_as_one all_defs (SD_aux(sd else init_env name in init_env (name ^ "/end"), uses -let fv_of_rd consider_var (DEC_aux (d,_)) = match d with - | DEC_reg(t,id) -> - init_env (string_of_id id), fv_of_typ consider_var mt mt t - | DEC_config(id,t,exp) -> - init_env (string_of_id id), fv_of_typ consider_var mt mt t - | DEC_alias(id,alias) -> - init_env (string_of_id id),mt - | DEC_typ_alias(t,id,alias) -> - init_env (string_of_id id), mt +let fv_of_rd consider_var (DEC_aux (d, annot)) = + (* When we get the free variables of a register, we have to ensure + that we expand all synonyms so we can pick up dependencies with + undefined_type function, even when type is indirected through a + synonym. *) + let open Type_check in + let env = env_of_annot annot in + match d with + | DEC_reg(t, id) -> + let t' = Env.expand_synonyms env t in + init_env (string_of_id id), + Nameset.union (fv_of_typ consider_var mt mt t) (fv_of_typ consider_var mt mt t') + | DEC_config(id, t, exp) -> + let t' = Env.expand_synonyms env t in + init_env (string_of_id id), + Nameset.union (fv_of_typ consider_var mt mt t) (fv_of_typ consider_var mt mt t') + | DEC_alias(id, alias) -> + init_env (string_of_id id), mt + | DEC_typ_alias(t, id, alias) -> + init_env (string_of_id id), mt let fv_of_def consider_var consider_scatter_as_one all_defs = function | DEF_kind kdef -> fv_of_kind_def consider_var kdef @@ -475,6 +486,8 @@ let fv_of_def consider_var consider_scatter_as_one all_defs = function List.fold_left Nameset.union Nameset.empty (List.map snd fvs) | DEF_scattered sdef -> fv_of_scattered consider_var consider_scatter_as_one all_defs sdef | DEF_reg_dec rdec -> fv_of_rd consider_var rdec + | DEF_constraint (id, _, _) -> + raise (Reporting.err_unreachable (id_loc id) __POS__ "Constraint should be re-written") let group_defs consider_scatter_as_one (Ast.Defs defs) = List.map (fun d -> (fv_of_def false consider_scatter_as_one defs d,d)) defs @@ -549,6 +562,15 @@ let scc ?(original_order : string list option) (g : graph) = let add_def_to_graph (prelude, original_order, defset, graph) d = let bound, used = fv_of_def false true [] d in + let used = match d with + | DEF_reg_dec _ -> + (* For a register, we need to ensure that any undefined_type + functions for types used by the register are placed before + the register declaration. *) + let undefineds = Nameset.map (fun name -> "undefined_" ^ name) used in + Nameset.union undefineds used + | _ -> used + in try (* A definition may bind multiple identifiers, e.g. "let (x, y) = ...". We add all identifiers to the dependency graph as a cycle. The actual |
