diff --git a/Makefile b/Makefile index 5136dd9a8b93c557310c9baea7309210b55371ed..cdfca959234201f053bf2b2cd8d43978fc1c3c56 100644 --- a/Makefile +++ b/Makefile @@ -543,6 +543,7 @@ KERNEL_CMO=\ src/kernel_internals/parsing/logic_parser.cmo \ src/kernel_internals/parsing/logic_lexer.cmo \ src/kernel_services/ast_queries/logic_typing.cmo \ + src/kernel_services/ast_queries/acsl_extension.cmo \ src/kernel_services/ast_queries/ast_info.cmo \ src/kernel_services/ast_data/ast.cmo \ src/kernel_services/ast_printing/cprint.cmo \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index f93a3797c6f1586aaeaa52de9858856bd5509e5b..3f43e26665fa03ad739e990fc8f99fc1e6d10fa9 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -525,6 +525,8 @@ src/kernel_services/ast_printing/printer_builder.mli: CEA_LGPL src/kernel_services/ast_printing/printer_tag.ml: CEA_LGPL src/kernel_services/ast_printing/printer_tag.mli: CEA_LGPL src/kernel_services/ast_queries/README.md: .ignore +src/kernel_services/ast_queries/acsl_extension.ml: CEA_LGPL +src/kernel_services/ast_queries/acsl_extension.mli: CEA_LGPL src/kernel_services/ast_queries/ast_info.ml: CEA_LGPL src/kernel_services/ast_queries/ast_info.mli: CEA_LGPL src/kernel_services/ast_queries/cil.ml: CIL diff --git a/src/kernel_services/ast_queries/acsl_extension.ml b/src/kernel_services/ast_queries/acsl_extension.ml new file mode 100644 index 0000000000000000000000000000000000000000..3354d9e42e67bd2742d56b7fc60a873fc69ff164 --- /dev/null +++ b/src/kernel_services/ast_queries/acsl_extension.ml @@ -0,0 +1,105 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* 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 +open Logic_typing +open Logic_ptree + +type extension_info = { + ext_status: bool ; + ext_typing: extension_typing ; + ext_visit: extension_visit ; + ext_printing: extension_printing ; +} +and extension_typing = + typing_context -> location -> lexpr list -> acsl_extension_kind +and extension_visit = + Cil.cilVisitor -> acsl_extension_kind -> acsl_extension_kind Cil.visitAction +and extension_printing = + Printer_api.extensible_printer_type -> Format.formatter -> + acsl_extension_kind -> unit + +(* Default extension *) + +let default_typing typing_context loc l = + let _ = loc in + let typing = typing_context.type_predicate typing_context (Lenv.empty ()) in + Ext_preds (List.map typing l) + +let default_visit _ _ = Cil.DoChildren + +let default_printing printer fmt = function + | Ext_id i -> Format.fprintf fmt "%d" i + | Ext_terms ts -> Pretty_utils.pp_list ~sep:",@ " printer#term fmt ts + | Ext_preds ps -> Pretty_utils.pp_list ~sep:",@ " printer#predicate fmt ps + +let default = { + ext_status = false ; + ext_typing = default_typing ; + ext_printing = default_printing ; + ext_visit = default_visit ; +} + +module Extensions = struct + let ext_tbl = Hashtbl.create 5 + + let find name = + try snd (Hashtbl.find ext_tbl name) + with Not_found -> + Kernel.fatal ~current:true "unsupported clause of name '%s'" name + + let category name = + Extlib.opt_map fst (Hashtbl.find_opt ext_tbl name) + + let is_extension = Hashtbl.mem ext_tbl + + let register category name info = + if is_extension name then + Kernel.warning ~wkey:Kernel.wkey_acsl_extension + "Trying to register ACSL extension %s twice. Ignoring second extension" + name + else Hashtbl.add ext_tbl name (category, info) + + let typing name typing_context loc es = + let ext_info = find name in + let status = ext_info.ext_status in + let typer = ext_info.ext_typing in + status, (typer typing_context loc es) + + let print name = (find name).ext_printing + let visit name = (find name).ext_visit +end + +(* Registration *) + +let register_behavior = + Extensions.register Ext_contract +let register_global = + Extensions.register Ext_global +let register_code_annot = + Extensions.register (Ext_code_annot Ext_here) +let register_code_annot_next_stmt = + Extensions.register (Ext_code_annot Ext_next_stmt) +let register_code_annot_next_loop = + Extensions.register (Ext_code_annot Ext_next_loop) +let register_code_annot_next_both = + Extensions.register (Ext_code_annot Ext_next_both) diff --git a/src/kernel_services/ast_queries/acsl_extension.mli b/src/kernel_services/ast_queries/acsl_extension.mli new file mode 100644 index 0000000000000000000000000000000000000000..f6114dec25091749e4fd34018700d8a8d90889c5 --- /dev/null +++ b/src/kernel_services/ast_queries/acsl_extension.mli @@ -0,0 +1,48 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* 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 +open Logic_typing +open Logic_ptree + +type extension_info = { + ext_status: bool ; + ext_typing: extension_typing ; + ext_visit: extension_visit ; + ext_printing: extension_printing ; +} +and extension_typing = + typing_context -> location -> lexpr list -> acsl_extension_kind +and extension_visit = + Cil.cilVisitor -> acsl_extension_kind -> acsl_extension_kind Cil.visitAction +and extension_printing = + Printer_api.extensible_printer_type -> Format.formatter -> + acsl_extension_kind -> unit + +val default: extension_info + +val register_behavior: string -> extension_info -> unit +val register_global: string -> extension_info -> unit +val register_code_annot: string -> extension_info -> unit +val register_code_annot_next_stmt: string -> extension_info -> unit +val register_code_annot_next_loop: string -> extension_info -> unit +val register_code_annot_next_both: string -> extension_info -> unit \ No newline at end of file