123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218openCilopenCilint(* Contributed by Nathan Cooprider *)letisOnee=matchgetIntegerewith|Somen->compare_cilintnone_cilint=0|_->false(* written by Zach *)letis_volatile_tptp=List.exists(function(Attr("volatile",_))->true|_->false)(typeAttrstp)(* written by Zach *)letis_volatile_vivi=letvi_vol=List.exists(function(Attr("volatile",_))->true|_->false)vi.vattrinlettyp_vol=is_volatile_tpvi.vtypeinvi_vol||typ_vol(*****************************************************************************
A collection of useful functions that were not already in CIL as far as I
could tell. However, I have been surprised before . . .
****************************************************************************)typesign=Signed|UnsignedexceptionNot_an_integer(*****************************************************************************
A bunch of functions for accessing integers. Originally written for
somebody who didn't know CIL and just wanted to mess with it at the
OCaml level.
****************************************************************************)letunbox_int_type(ye:typ):(int*sign)=lettp=unrollTypeyeinlets=matchtpwithTInt(i,_)->if(isSignedi)thenSignedelseUnsigned|_->raiseNot_an_integerin(bitsSizeOftp),sexceptionWeird_bitwidth(* (int64 * int * sign) : exp *)letocaml_int_to_cilvns=letchar_size=bitsSizeOfcharTypeinletint_size=bitsSizeOfintTypeinletshort_size=bitsSizeOf(TInt(IShort,[]))inletlong_size=bitsSizeOflongTypeinletlonglong_size=bitsSizeOf(TInt(ILongLong,[]))inletint128_size=bitsSizeOf(TInt(IInt128,[]))inleti=matchswithSigned->if(n=char_size)thenISCharelseif(n=int_size)thenIIntelseif(n=short_size)thenIShortelseif(n=long_size)thenILongelseif(n=longlong_size)thenILongLongelseif(n=int128_size)thenIInt128elseraiseWeird_bitwidth|Unsigned->if(n=char_size)thenIUCharelseif(n=int_size)thenIUIntelseif(n=short_size)thenIUShortelseif(n=long_size)thenIULongelseif(n=longlong_size)thenIULongLongelseif(n=int128_size)thenIUInt128elseraiseWeird_bitwidthinkinteger64iv(*****************************************************************************
a couple of type functions that I thought would be useful:
****************************************************************************)letrecisCompositeTypetp=matchtpwithTComp_->true|TPtr(x,_)->isCompositeTypex|TArray(x,_,_)->isCompositeTypex|TFun(x,_,_,_)->isCompositeTypex|TNamed(x,_)->isCompositeTypex.ttype|_->false(** START OF deepHasAttribute ************************************************)letvisited=ref[]classattribute_checkertargetrflag=object(self)inheritnopCilVisitormethod!vtypet=matchtwithTComp(cinfo,a)->if(not(List.exists(funx->cinfo.cname=x)!visited))thenbeginvisited:=cinfo.cname::!visited;List.iter(funf->if(hasAttributetargetf.fattr)thenrflag:=trueelseignore(visitCilType(newattribute_checkertargetrflag)f.ftype))cinfo.cfields;end;DoChildren|TNamed(t1,a)->if(not(List.exists(funx->t1.tname=x)!visited))thenbeginvisited:=t1.tname::!visited;ignore(visitCilType(newattribute_checkertargetrflag)t1.ttype);end;DoChildren|_->DoChildrenmethod!vattr(Attr(name,params))=if(name=target)thenrflag:=true;DoChildrenendletdeepHasAttributest=letfound=reffalseinvisited:=[];ignore(visitCilType(newattribute_checkersfound)t);!found(** END OF deepHasAttribute **************************************************)(** Stuff from ptranal, slightly modified ************************************)(*****************************************************************************
A transformation to make every instruction be in its own statement.
****************************************************************************)classcallBBVisitor=objectinheritnopCilVisitormethod!vstmts=matchs.skindwithInstr(il)->beginif(List.lengthil>1)thenletlist_of_stmts=Util.list_map(funone_inst->mkStmtOneInstrone_inst)ilinletblock=mkBlocklist_of_stmtsins.skind<-Blockblock;ChangeTo(s)elseSkipChildrenend|_->DoChildrenmethod!vvdec_=SkipChildrenmethod!vexpr_=SkipChildrenmethod!vlval_=SkipChildrenmethod!vtype_=SkipChildrenendletone_instruction_per_statementf=letthisVisitor=newcallBBVisitorinvisitCilFileSameGlobalsthisVisitorf(*****************************************************************************
A transformation that gives each variable a unique identifier.
****************************************************************************)classvidVisitor=objectinheritnopCilVisitorvalcount=ref0method!vvdecvi=vi.vid<-!count;incrcount;SkipChildrenendletglobally_unique_vidsf=letthisVisitor=newvidVisitorinvisitCilFileSameGlobalsthisVisitorf(** End of stuff from ptranal ************************************************)classsidVisitor=objectinheritnopCilVisitorvalcount=ref0method!vstmts=s.sid<-!count;incrcount;DoChildrenendletglobally_unique_sidsf=letthisVisitor=newsidVisitorinvisitCilFileSameGlobalsthisVisitorf(** Comparing expressions without a Out_of_memory error **********************)letcompare_expxy=comparexy