123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)openRangesopenCil_typesmoduleDomain=Cil_datatype.Compinfo.SetletbytesSizeOfty=tryCil.bytesSizeOftywith|Cil.SizeOfError(_,{tnode=TFun_})->1|Cil.SizeOfError(_,{tnode=TVoid})->1letbitsSizeOfty=tryCil.bitsSizeOftywith|Cil.SizeOfError(_,{tnode=TFun_})->8|Cil.SizeOfError(_,{tnode=TVoid})->8typefield=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(Cil_const.mk_tcompa.data.fcomp)inletsb=Cil.bitsSizeOf(Cil_const.mk_tcompb.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[]letpp_slicesfmt=function|[Fieldf]->Format.fprintffmt".%s"f.fname|[Fieldf;Fieldg]|[Fieldf;_;Fieldg]->Format.fprintffmt"(%s-%s)"f.fnameg.fname|slices->List.iter(pp_slicefmt)slicesletprettyfieldsfmtrg=pp_slicesfmt@@spanfieldsrgletpslicefmt~fields~offset~length=pp_slicesfmt@@spanfields{offset;length;data=()}