123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112(**************************************************************************)(* *)(* This file is part of the Frama-C's Lannotate plug-in. *)(* *)(* Copyright (C) 2012-2025 *)(* 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 LICENSE) *)(* *)(**************************************************************************)openCil_typesopenAst_constletunk_loc=Cil_datatype.Location.unknown(* Est-ce qu'on peut recup' la loc plus simplement? *)letget_fundec_locdec=letglob=Ast.def_or_last_decldec.svarinmatchglobwith|GFun(_,loc)->loc|_->unk_loc(** A visitor that adds a label at the start of each statement
i.e. :
-Start of a function
-Goto/Return
-Each block of a If
-In Loops
-After each C labels
*)letvisitormk_label=object(self)inheritVisitor.frama_c_inplacemethod!vfuncdec=ifAnnotators.shouldInstrumentFundec.svarthenletl=mk_label(Exp_builder.one())[](get_fundec_locdec)inCil.DoChildrenPost(funres->res.sbody.bstmts<-l::res.sbody.bstmts;res)elseCil.SkipChildrenmethod!vstmt_auxstmt=matchstmt.skindwith|Goto(_,loc)|Return(_,loc)->letl=mk_label(Exp_builder.one())[]locinstmt.skind<-Block(Cil.mkBlock[l;Stmt_builder.mkstmt.skind]);Cil.SkipChildren|If(e,b1,b2,loc)->letl1=mk_label(Exp_builder.one())[]locinletnb1=Cil.visitCilBlock(self:>Cil.cilVisitor)b1inletl2=mk_label(Exp_builder.one())[]locinletnb2=Cil.visitCilBlock(self:>Cil.cilVisitor)b2innb1.bstmts<-l1::nb1.bstmts;nb2.bstmts<-l2::nb2.bstmts;stmt.skind<-(If(e,nb1,nb2,loc));Cil.SkipChildren|Loop_->Cil.DoChildrenPost(funres->matchres.skindwith|Loop(ca,b,loc,s1,s2)->letlb=mk_label(Exp_builder.one())[]locinb.bstmts<-lb::b.bstmts;res.skind<-(Loop(ca,b,loc,s1,s2));res|_->assertfalse)|_->Cil.DoChildrenPost(funres->ifres.labels<>[]thenbeginletloc=matchList.hdstmt.labelswith|Label(_,l,_)|Case(_,l)|Defaultl->linletlb=mk_label(Exp_builder.one())[]locinres.skind<-beginmatchres.skindwith|Instr(Skip_)->lb.skind|_->Block(Cil.mkBlock[lb;Stmt_builder.mkres.skind]);end;resendelseres)endincludeAnnotators.Register(structletname="STMT"lethelp="Statement Coverage"letapplyfast=Visitor.visitFramacFileSameGlobals(visitorf)astend)