12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2024 *)(* 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). *)(* *)(**************************************************************************)openRangesopenCil_typesmoduleDomain=Cil_datatype.Compinfo.Settypefield=fieldinforangetypedomain=Domain.t(* support for associating offsets to field name *)letiter=Domain.iterletunion=Domain.unionletempty=Domain.emptyletsingleton(fd:fieldinfo)=Domain.singletonfd.fcomp(* minimal offset first, then minimal length, then largest struct *)letcompare(a:field)(b:field)=letcmp=a.offset-b.offsetinifcmp<>0thencmpelseletcmp=a.length-b.lengthinifcmp<>0thencmpelseletsa=Cil.bitsSizeOf(TComp(a.data.fcomp,[]))inletsb=Cil.bitsSizeOf(TComp(b.data.fcomp,[]))insb-saletfind_all(fields:domain)(rg:_range)=List.sortcompare@@Domain.fold(funcfds->List.fold_left(funfdsfd->letofs,len=Cil.fieldBitsOffsetfdinifrg.offset<=ofs&&ofs+len<=rg.offset+rg.lengththen{offset=ofs;length=len;data=fd}::fdselsefds)fds@@Option.value~default:[]c.cfields)fields[]letfindfieldsrg=matchfind_allfieldsrgwith|[]->None|fr::_->Somefrtypeslice=Bitsofint|Fieldoffieldinfoletpp_bitsfmtn=ifn<>0thenFormat.fprintffmt"#%db"nletpp_slicefmt=function|Bitsn->pp_bitsfmtn|Fieldfd->Format.fprintffmt".%s"fd.fnameletpadpqs=letn=q-pinifn>0thenBitsn::selsesletlast(rg:_range)=rg.offset+rg.lengthletspanfieldsrg=matchfind_allfieldsrgwith|[]->[Bitsrg.length]|fr::frs->padrg.offsetfr.offset@@Fieldfr.data::letp=lastfrinletq=lastrginmatchList.rev@@List.filter(funr->p<=r.offset)frswith|[]->padpq[]|lr::_->padplr.offset@@Fieldlr.data::pad(lastlr)q[]letprettyfieldsfmtrg=List.iter(pp_slicefmt)@@spanfieldsrgletpslicefmt~fields~offset~length=List.iter(pp_slicefmt)@@spanfields{offset;length;data=()}