diff --git a/src/kernel_internals/parsing/logic_parser.mly b/src/kernel_internals/parsing/logic_parser.mly index 08a045b18ce952a9142cf81e8acecc4d9e110d5c..01d7509c06f6d75a7962b12a604c1143980ea032 100644 --- a/src/kernel_internals/parsing/logic_parser.mly +++ b/src/kernel_internals/parsing/logic_parser.mly @@ -259,6 +259,23 @@ let cv_ghost = Attr("ghost", []) let toplevel_pred tp_kind tp_statement = { tp_kind; tp_statement } + + let extension ext_name ext_plugin ext_content = + {ext_name; ext_plugin; ext_content} + + let global_extension gext_name gext_plugin gext_kind gext_content = + Ext_extension {gext_name; gext_plugin; gext_kind; gext_content} + + let import loader module_name module_alias = + let import_loader = + match loader with + | None -> None + | Some (loader_name, loader_plugin) -> + Some {loader_name;loader_plugin} + in + LDimport { import_loader; module_name; module_alias} + + %} /*****************************************************************************/ @@ -1258,7 +1275,8 @@ ne_simple_clauses: { let allocation,assigns,post_cond,extended = snd $4 in let name, plugin = $1 in let processed = Logic_env.preprocess_extension ~plugin name $2 in - allocation,assigns,post_cond,(name, plugin, processed)::extended + let ext = extension name plugin processed in + allocation,assigns,post_cond,ext::extended } | post_cond_kind lexpr clause_kw { missing $loc($2) ";" $3 } | allocation clause_kw { missing $loc($1) ";" $2 } @@ -1478,21 +1496,21 @@ loop_variant: loop_grammar_extension: | LOOP EXT_CODE_ANNOT extension_content SEMICOLON { let open Cil_types in - let ext, plugin = $2 in + let name, plugin = $2 in try - begin match Logic_env.extension_category ~plugin ext with + begin match Logic_env.extension_category ~plugin name with | Ext_code_annot (Ext_next_loop | Ext_next_both) -> - let processed = Logic_env.preprocess_extension ~plugin ext $3 in - (ext, plugin, processed) + let processed = Logic_env.preprocess_extension ~plugin name $3 in + {ext_name = name; ext_plugin = plugin; ext_content = processed} | Ext_code_annot (Ext_here | Ext_next_stmt) -> raise (Not_well_formed - (loc $loc($2), ext ^ " is not a loop annotation extension")) + (loc $loc($2), name ^ " is not a loop annotation extension")) | _ -> raise Not_found end with Not_found -> Kernel.fatal ~source:(pos $startpos($2)) - "%s is not a code annotation extension. Parser got wrong lexeme." ext + "%s is not a code annotation extension. Parser got wrong lexeme." name } ; @@ -1527,12 +1545,13 @@ code_annotation: | EXT_CODE_ANNOT extension_content SEMICOLON { fun bhvs -> let open Cil_types in - let ext, plugin = $1 in + let name, plugin = $1 in try - begin match Logic_env.extension_category ~plugin ext with + begin match Logic_env.extension_category ~plugin name with | Ext_code_annot (Ext_here | Ext_next_stmt | Ext_next_both) -> - let processed = Logic_env.preprocess_extension ~plugin ext $2 in - Logic_ptree.AExtended(bhvs,false,(ext,plugin,processed)) + let processed = Logic_env.preprocess_extension ~plugin name $2 in + let ext = extension name plugin processed in + Logic_ptree.AExtended(bhvs,false,ext) | Ext_code_annot Ext_next_loop -> raise (Not_well_formed @@ -1540,12 +1559,12 @@ code_annotation: Printf.sprintf "%s is a loop annotation extension. It can't be used as a \ plain code annotation extension. Did you mean 'loop %s'?" - ext ext)) + name name)) | _ -> raise Not_found end with Not_found -> Kernel.fatal ~source:(pos $startpos($1)) - "%s is not a code annotation extension. Parser got wrong lexeme" ext + "%s is not a code annotation extension. Parser got wrong lexeme" name } ; @@ -1571,14 +1590,15 @@ ext_decl: | EXT_GLOBAL extension_content SEMICOLON { let name, plugin = $1 in let processed = Logic_env.preprocess_extension ~plugin name $2 in - Ext_lexpr(name, plugin, processed) + let ext = extension name plugin processed in + Ext_lexpr ext } | EXT_GLOBAL_BLOCK any_identifier LBRACE ext_decls RBRACE { let name, plugin = $1 in let processed_id,processed_block = Logic_env.preprocess_extension_block ~plugin name ($2,$4) in - Ext_extension(name, plugin, processed_id, processed_block) + global_extension name plugin processed_id processed_block } ; @@ -1695,13 +1715,13 @@ logic_def: | MODULE push_module_name LBRACE logic_decls RBRACE { pop_module_types () ; LDmodule($2,$4) } | IMPORT mId = module_name SEMICOLON - { LDimport(None,mId,None) } + { import None mId None } | IMPORT mId = module_name AS id = IDENTIFIER SEMICOLON - { LDimport(None,mId,Some id) } + { import None mId (Some id) } | IMPORT loader = ext_loader mId = module_name SEMICOLON - { LDimport(Some loader,mId,None) } + { import (Some loader) mId None } | IMPORT loader = ext_loader mId = module_name AS id = IDENTIFIER SEMICOLON - { LDimport(Some loader,mId,Some id) } + { import (Some loader) mId (Some id) } | TYPE poly_id_type_add_typename EQUAL typedef SEMICOLON { let (id,tvars) = $2 in exit_type_variables_scope (); diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index d9929b8846d32ed14dec027c0d5dd88ff43503b2..4d639ed255a09ae499690bfd07c50c50d7c8e2e9 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -9820,9 +9820,12 @@ and doBody local_env (blk: Cabs.block) : chunk = s.Logic_ptree.spec_behavior, true | CODE_ANNOT - (Logic_ptree.AExtended(_,is_loop,(name,plugin,_)),loc) -> + (Logic_ptree.AExtended(_,is_loop,ext),loc) -> let source = fst loc in - (match Logic_env.extension_category ~plugin name, is_loop with + let kind = + Logic_env.extension_category ~plugin:ext.ext_plugin ext.ext_name + in + (match kind, is_loop with | Ext_code_annot Ext_here, false -> [], false | Ext_code_annot Ext_next_stmt, false -> [], true | Ext_code_annot Ext_next_loop, true -> [], false @@ -9832,20 +9835,20 @@ and doBody local_env (blk: Cabs.block) : chunk = warning ~source ~wkey:wkey_acsl_extension "%s is a code annotation extension, \ - but used here as a loop annotation" name); + but used here as a loop annotation" ext.ext_name); [], false | Ext_code_annot Ext_next_loop, false -> Kernel.( warning ~source ~wkey:wkey_acsl_extension "%s is a loop annotation extension, \ - but used here as a code annotation" name); + but used here as a code annotation" ext.ext_name); [], false | (Ext_global | Ext_contract), _ -> Kernel.( warning ~source ~wkey:wkey_acsl_extension - "%s is not a code annotation extension" name); + "%s is not a code annotation extension" ext.ext_name); [], false) | _ -> [], false in diff --git a/src/kernel_services/ast_data/cil_types.ml b/src/kernel_services/ast_data/cil_types.ml index 488707721d9c36e48739e793b315a7b49001df71..49c18c4fd529f876c026412d2a7c6ebd5e5db20f 100644 --- a/src/kernel_services/ast_data/cil_types.ml +++ b/src/kernel_services/ast_data/cil_types.ml @@ -1793,6 +1793,14 @@ and code_annotation = { (** behavior of a function. *) and funbehavior = behavior +(** loader type used by Dmodules. + @since Frama-c+dev +*) +and loader = { + loader_name: string; + loader_plugin: string; +} + (** global annotations, not attached to a statement or a function. *) and global_annotation = | Dfun_or_pred of logic_info * location @@ -1801,8 +1809,10 @@ and global_annotation = * attributes * location (** associated terms, reading function, writing function *) | Daxiomatic of string * global_annotation list * attributes * location - (** last option is the external loader responsible for the module importer *) - | Dmodule of string * global_annotation list * attributes * (string * string) option * location + (** last option is the external loader(name, plugin) responsible for the + module importer *) + | Dmodule of + string * global_annotation list * attributes * loader option * location | Dtype of logic_type_info * location (** declaration of a logic type. *) | Dlemma of string * logic_label list * string list * diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index c2468724ed7c9421679d5b4d59c7214663e60bce..fc7d05c72804a2d36f0dbf0c858ef8de51dd3097 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -3284,10 +3284,10 @@ class cil_printer () = object (self) (self#typ None) mfi.mi_base_type (self#logic_type (Some print_decl)) mfi.mi_field_type - method private pp_loader fmt (name, plugin) = - if Datatype.String.equal plugin "kernel" - then pp_print_string fmt name - else fprintf fmt "\\%s::%s" plugin name + method private pp_loader fmt loader = + if Datatype.String.equal loader.loader_plugin "kernel" + then pp_print_string fmt loader.loader_name + else fprintf fmt "\\%s::%s" loader.loader_plugin loader.loader_name method global_annotation fmt = function | Dtype_annot (a,_) -> diff --git a/src/kernel_services/ast_printing/cil_types_debug.ml b/src/kernel_services/ast_printing/cil_types_debug.ml index e44d426765ac4ddb4fc5c900634df1ef83c7c46a..4a1ae03abc0409845ad9d794b96efe4fc24b9f85 100644 --- a/src/kernel_services/ast_printing/cil_types_debug.ml +++ b/src/kernel_services/ast_printing/cil_types_debug.ml @@ -972,8 +972,8 @@ and pp_global_annotation fmt = function (pp_list pp_global_annotation) global_annotation_list pp_attributes attributes pp_location location | Dmodule(string,global_annotation_list,attributes,loader,location) -> - let pp_loader fmt (name, plugin) = - Format.fprintf fmt "(%s, %s)" name plugin + let pp_loader fmt loader = + Format.fprintf fmt "(%s, %s)" loader.loader_name loader.loader_plugin in Format.fprintf fmt "Dmodule(%a,%a,%a,%a,%a)" pp_string string (pp_list pp_global_annotation) global_annotation_list diff --git a/src/kernel_services/ast_printing/logic_print.ml b/src/kernel_services/ast_printing/logic_print.ml index acbddebd63d65a1971b586b8c9bfcb50429189bc..91bbf80e966b1defd19735cf112733140c021122 100644 --- a/src/kernel_services/ast_printing/logic_print.ml +++ b/src/kernel_services/ast_printing/logic_print.ml @@ -310,7 +310,7 @@ let print_model_annot fmt ty = (print_logic_type None) ty.model_type ty.model_name -let print_plugin fmt (plugin, name) = +let print_plugin fmt (name, plugin) = if Datatype.String.equal plugin "kernel" then pp_print_string fmt name else fprintf fmt "\\%s::%s" plugin name @@ -318,12 +318,15 @@ let print_plugin fmt (plugin, name) = let rec print_extended_decl fmt d = let aux fmt d = print_extended_decl fmt d.extended_node in match d with - | Ext_lexpr(name, plugin, d) -> + | Ext_lexpr ext -> fprintf fmt "@[<2>%a@ %a@]" - print_plugin (plugin,name) (pp_list ~sep:",@ " print_lexpr) d - | Ext_extension(name, plugin, id,d) -> + print_plugin (ext.ext_name, ext.ext_plugin) + (pp_list ~sep:",@ " print_lexpr) ext.ext_content + | Ext_extension ext -> fprintf fmt "@[<2>%a@ %s@ {@\n%a@]@\n}" - print_plugin (plugin,name) id (pp_list ~sep:"@\n" aux) d + print_plugin (ext.gext_name, ext.gext_plugin) + ext.gext_kind + (pp_list ~sep:"@\n" aux) ext.gext_content let rec print_decl fmt d = match d.decl_node with @@ -381,11 +384,14 @@ let rec print_decl fmt d = | LDmodule (name,ds) -> fprintf fmt "@[<2>module@ %s@ {@\n%a@]@\n}" name (pp_list ~sep:"@\n" print_decl) ds - | LDimport (loader,mId,asId) -> + | LDimport import -> fprintf fmt "@[<2>import" ; - Option.iter (fprintf fmt "%a:" print_plugin) loader ; - fprintf fmt "@ %s" mId ; - Option.iter (fprintf fmt "@ \\as %s") asId ; + Option.iter (fun loader -> + let name, plugin = loader.loader_name, loader.loader_plugin in + fprintf fmt "%a:" print_plugin (name, plugin) + ) import.import_loader ; + fprintf fmt "@ %s" import.module_name ; + Option.iter (fprintf fmt "@ \\as %s") import.module_alias ; fprintf fmt ";@]@\n}" | LDinvariant (s,e) -> fprintf fmt "@[<2>invariant@ %s:@ %a;@]" s print_lexpr e @@ -464,9 +470,9 @@ let print_spec fmt spec = ~sep:"@\n" ~suf:"@\n" (pp_list ~sep:",@ " pp_print_string)) spec.spec_disjoint_behaviors -let print_extension fmt (name, plugin, ext) = - fprintf fmt "%a %a" print_plugin (plugin,name) - (pp_list ~sep:",@ " print_lexpr) ext +let print_extension fmt ext = + fprintf fmt "%a %a" print_plugin (ext.ext_name, ext.ext_plugin) + (pp_list ~sep:",@ " print_lexpr) ext.ext_content let print_code_annot fmt ca = let print_behaviors fmt bhvs = diff --git a/src/kernel_services/ast_queries/acsl_extension.ml b/src/kernel_services/ast_queries/acsl_extension.ml index 03370128e86f0c135ded36f7b6680c05375c7f8d..ee109a99b5c7be8ef73069da84cb111c726672d5 100644 --- a/src/kernel_services/ast_queries/acsl_extension.ml +++ b/src/kernel_services/ast_queries/acsl_extension.ml @@ -278,7 +278,7 @@ module Extensions = struct let preprocess_block ~plugin name = (find_block ~plugin name).preprocessor - let typing_gen ~status ~typer name typing_context loc es = + let typing_gen ~typer ~status name typing_context loc es = let normal_error = ref false in let has_error _ = normal_error := true in let wrapper = diff --git a/src/kernel_services/ast_queries/logic_typing.ml b/src/kernel_services/ast_queries/logic_typing.ml index 525a5e7b2d8bc8cd415c9bf129cebe6b266decac..69cb0cb35c6ff584a0287e04eea2b79cdf7a8f68 100644 --- a/src/kernel_services/ast_queries/logic_typing.ml +++ b/src/kernel_services/ast_queries/logic_typing.ml @@ -3783,17 +3783,20 @@ struct old_behaviors behaviors - let type_extended ~typing_context ~loc (name, plugin, ps) = - let loc = match ps with + let type_extended ~typing_context ~loc {ext_name; ext_plugin; ext_content} = + let loc = match ext_content with | [] -> loc | p::_ -> p.lexpr_loc in - if Extensions.is_extension ~plugin name then - let status , kind = Extensions.typer name ~plugin ~typing_context ~loc ps in - Logic_const.new_acsl_extension ~plugin name loc status kind + if Extensions.is_extension ~plugin:ext_plugin ext_name then + let status , kind = + Extensions.typer ext_name ~plugin:ext_plugin ~typing_context ~loc + ext_content + in + Logic_const.new_acsl_extension ~plugin:ext_plugin ext_name loc status kind else C.error - loc "No type-checking function registered for extension %s" name + loc "No type-checking function registered for extension %s" ext_name (* This module is used to sort the list of behaviors in [complete] and [disjoint] clauses, in order to remove duplicate clauses. *) @@ -3996,7 +3999,8 @@ struct let env = loop_annot_env () in let ctxt = base_ctxt env in Cil_types.AAssigns(behav, type_assign ctxt ~accept_formal:true env a) - | AExtended (behav, is_loop, (name, plugin, _ as ext)) -> + | AExtended (behav, is_loop, ext) -> + let name, plugin = ext.ext_name, ext.ext_plugin in let kind = Logic_env.extension_category ~plugin name in let pre_state, post_state = match kind,is_loop with @@ -4327,10 +4331,12 @@ struct pop_imports () ; Some (Dmodule(name,l,[],None,loc)) - | LDimport(None,id,alias) -> - add_import ?alias id ; None + | LDimport ({import_loader = None; _} as import) -> + add_import ?alias:import.module_alias import.module_name ; None - | LDimport(Some (name, plugin) as loader,id,alias) -> + | LDimport ({import_loader = Some loader; _} as import) -> + let name, plugin = loader.loader_name, loader.loader_plugin in + let id = import.module_name in let annot = match Logic_env.Modules.find id with | None, oldloc -> @@ -4349,9 +4355,12 @@ struct let builder = make_module_builder decls id in let path = Logic_utils.longident id in Extensions.importer ~plugin name ~builder ~loc path ; - Logic_env.Modules.add id (loader,loc) ; - Some (Dmodule(id,List.rev !decls,[],loader,loc)) - in add_import ?alias id ; annot + Logic_env.Modules.add id (Some (name, plugin),loc) ; + let loader : Cil_types.loader = + {loader_name = name; loader_plugin = plugin} + in + Some (Dmodule(id,List.rev !decls,[],Some loader,loc)) + in add_import ?alias:import.module_alias id ; annot | LDtype(name,l,def) -> let env = init_type_variables loc l in @@ -4498,16 +4507,21 @@ struct let wvi_opt = get_volatile_fct checks_writes_fct wr_opt in Some (Dvolatile (tsets, rvi_opt, wvi_opt, [], loc)) - | LDextended (Ext_lexpr(name, plugin, content)) -> + | LDextended (Ext_lexpr ext) -> + let plugin, name = ext.ext_plugin, ext.ext_name in let typing_context = base_ctxt (Lenv.empty ()) in - let status,tcontent = Extensions.typer ~plugin name ~typing_context ~loc content in + let status,tcontent = + Extensions.typer ~plugin name ~typing_context ~loc ext.ext_content + in let textended = Logic_const.new_acsl_extension ~plugin name loc status tcontent in Some (Dextended (textended, [], loc)) - | LDextended (Ext_extension (name, plugin, kind, content)) -> + | LDextended (Ext_extension gext) -> + let plugin, name = gext.gext_plugin, gext.gext_name in let typing_context = base_ctxt (Lenv.empty ()) in let status,tcontent = - Extensions.typer_block name ~plugin ~typing_context ~loc (kind,content) + Extensions.typer_block name ~plugin ~typing_context ~loc + (gext.gext_kind,gext.gext_content) in let textended = Logic_const.new_acsl_extension ~plugin name loc status tcontent in Some (Dextended (textended, [], loc)) diff --git a/src/kernel_services/parsetree/logic_ptree.ml b/src/kernel_services/parsetree/logic_ptree.ml index 2315b025d2c09ad278ef14f23770de394d537342..2669ced475387e4835a49716b5079143ea86bcb5 100644 --- a/src/kernel_services/parsetree/logic_ptree.ml +++ b/src/kernel_services/parsetree/logic_ptree.ml @@ -168,7 +168,11 @@ type toplevel_predicate = (** ACSL extension. @before Frama-C+dev Was of type [string * lexpr list]. *) -type extension = string * string * lexpr list +type extension = { + ext_name: string; + ext_plugin: string; + ext_content: lexpr list; +} (** type invariant. *) type type_annot = {inv_name: string; @@ -189,6 +193,14 @@ type typedef = (** sum type, list of constructors *) | TDsyn of logic_type (** synonym of an existing type *) +type loader = { + loader_name: string; + loader_plugin: string; +} +(** loader type used by module importers. + @since Frama-C+dev +*) + (** global declarations. *) type decl = { decl_node : decl_node; (** kind of declaration. *) @@ -250,7 +262,11 @@ and decl_node = | LDmodule of string * decl list (** [LDmodule(id,decls)] represents a module of axiomatic definitions.*) - | LDimport of (string * string) option * string * string option + | LDimport of { + import_loader: loader option; + module_name: string; + module_alias: string option; + } (** [LDimport(loader,module,alias)] imports symbols from module using the specified loader, with optional alias.*) @@ -288,10 +304,15 @@ and variant = lexpr * string option (** Global ACSL extension. *) and global_extension = - | Ext_lexpr of string * string * lexpr list + | Ext_lexpr of extension (** @before Frama-C+dev Was of type [string * lexpr list]. *) - | Ext_extension of string * string * string * extended_decl list + | Ext_extension of { + gext_name:string; + gext_plugin:string; + gext_kind: string; + gext_content: extended_decl list; + } (** @before Frama-C+dev Was of type [string * string * extended_decl list]. *) and extended_decl = { diff --git a/tests/spec/Extend_recursive_preprocess.ml b/tests/spec/Extend_recursive_preprocess.ml index a4a0b4bf026316bca8a406f026c5e96bafffff1c..238da2082829c7c7e24bb9b5492d0f7425b6fd55 100644 --- a/tests/spec/Extend_recursive_preprocess.ml +++ b/tests/spec/Extend_recursive_preprocess.ml @@ -12,11 +12,17 @@ let ext_typing_fooo _typing_context _loc l = let ext_typing_block typing_context loc_here node = match node.extended_node with - | Ext_lexpr (name,plugin,data) -> + | Ext_lexpr ext -> + let name, plugin, data = ext.ext_name, ext.ext_plugin, ext.ext_content in let status,kind = Logic_typing.get_typer ~plugin name ~typing_context ~loc:node.extended_loc data in Logic_const.new_acsl_extension ~plugin name loc_here status kind - | Ext_extension (name, plugin, id, data) -> - let status,kind = Logic_typing.get_typer_block ~plugin name ~typing_context ~loc:node.extended_loc (id,data) in + | Ext_extension gext -> + let name, plugin = gext.gext_name, gext.gext_plugin in + let kind, data = gext.gext_kind, gext.gext_content in + let status,kind = + Logic_typing.get_typer_block ~plugin name ~typing_context + ~loc:node.extended_loc (kind,data) + in Logic_const.new_acsl_extension ~plugin name loc_here status kind let ext_typing_foo typing_context loc (s,d) =