123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2019 The MOPSA Project. *)(* *)(* This program is free software: 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, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program 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. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)openMopsaopenAstletrecexprs_in_init=function|C_init_expre->[e]|C_init_implicit_->[]|C_init_list(l,filler)->letel1=l|>List.fold_left(funaccinit->acc@exprs_in_initinit)[]inletel2=exprs_in_init_optionfillerinel1@el2andexprs_in_init_option=function|None->[]|Someinit->exprs_in_initinitletrecinit_from_exprsexprsinit=matchinit,exprswith|C_init_expr_,e::tl->C_init_expre,tl|C_init_implicitt,exprs->C_init_implicitt,exprs|C_init_list(l,filler),exprs->letl,exprs=l|>List.fold_left(fun(init_list,exprs)init->letinit,exprs=init_from_exprsexprsinitin(init::init_list,exprs))([],exprs)inletfiller,exprs=init_option_from_exprsexprsfillerinC_init_list(List.revl,filler),exprs|_->assertfalseandinit_option_from_exprsexprsinit=matchinit,exprswith|None,exprs->None,exprs|Someinit,exprs->letinit,exprs=init_from_exprsexprsinitinSomeinit,exprslet()=register_expr_visitor(fundefaultexp->matchekindexpwith|E_c_conditional(cond,body,orelse)->{exprs=[cond;body;orelse];stmts=[]},(function|{exprs=[cond;body;orelse]}->{expwithekind=E_c_conditional(cond,body,orelse)}|_->assertfalse)|E_c_array_subscript(arr,idx)->{exprs=[arr;idx];stmts=[]},(function|{exprs=[arr;idx]}->{expwithekind=E_c_array_subscript(arr,idx)}|_->assertfalse)|E_c_member_access(rcd,idx,fld)->{exprs=[rcd];stmts=[]},(function|{exprs=[rcd]}->{expwithekind=E_c_member_access(rcd,idx,fld)}|_->assertfalse)|E_c_function(f)->leafexp|E_c_builtin_functionf->leafexp|E_c_builtin_call(f,args)->{exprs=args;stmts=[]},(function|{exprs=args}->{expwithekind=E_c_builtin_call(f,args)})|E_c_arrow_access(p,idx,fld)->{exprs=[p];stmts=[]},(function|{exprs=[p]}->{expwithekind=E_c_arrow_access(p,idx,fld)}|_->assertfalse)|E_c_assign(lval,rval)->{exprs=[lval;rval];stmts=[]},(function|{exprs=[lval;rval]}->{expwithekind=E_c_assign(lval,rval)}|_->assertfalse)|E_c_compound_assign(lval,pretyp,op,rval,posttyp)->{exprs=[lval;rval];stmts=[]},(function|{exprs=[lval;rval]}->{expwithekind=E_c_compound_assign(lval,pretyp,op,rval,posttyp)}|_->assertfalse)|E_c_comma(e1,e2)->{exprs=[e1;e2];stmts=[]},(function|{exprs=[e1;e2]}->{expwithekind=E_c_comma(e1,e2)}|_->assertfalse)|E_c_increment(dir,loc,e)->{exprs=[e];stmts=[]},(function|{exprs=[e]}->{expwithekind=E_c_increment(dir,loc,e)}|_->assertfalse)|E_c_address_of(e)->{exprs=[e];stmts=[]},(function|{exprs=[e]}->{expwithekind=E_c_address_of(e)}|_->assertfalse)|E_c_deref(p)->{exprs=[p];stmts=[]},(function|{exprs=[p]}->{expwithekind=E_c_deref(p)}|_->assertfalse)|E_c_cast(e,is_implicit)->{exprs=[e];stmts=[]},(function|{exprs=[e]}->{expwithekind=E_c_cast(e,is_implicit)}|_->assertfalse)|E_c_predefined_->leafexp|E_c_var_argsarg->{exprs=[arg];stmts=[]},(function|{exprs=[arg]}->{expwithekind=E_c_var_argsarg}|_->assertfalse)|E_c_atomic(op,e1,e2)->{exprs=[e1;e2];stmts=[]},(function|{exprs=[e1;e2]}->{expwithekind=E_c_atomic(op,e1,e2)}|_->assertfalse)|E_c_statement(s)->{exprs=[];stmts=[s]},(function|{stmts=[s]}->{expwithekind=E_c_statement(s)}|_->assertfalse)|E_c_block_objectee->{exprs=[ee];stmts=[]},(function|{exprs=[ee]}->{expwithekind=E_c_block_object(ee)}|_->assertfalse)|_->defaultexp);register_stmt_visitor(fundefaultstmt->matchskindstmtwith|S_program({prog_kind=C_program_},_)->Exceptions.panic"visitor of C_program not yet implemented"|S_c_declaration(v,init,scope)->letexprs=exprs_in_init_optioninitin{exprs;stmts=[]},(function{exprs}->letinit,_=init_option_from_exprsexprsinitin{stmtwithskind=S_c_declaration(v,init,scope)})|S_c_do_while(body,cond)->{exprs=[cond];stmts=[body]},(function|{exprs=[cond];stmts=[body]}->{stmtwithskind=S_c_do_while(body,cond)}|_->assertfalse)|S_c_for(init,cond,incr,body)->letexprs=matchcond,incrwith|Somecond,Someincr->[cond;incr]|Somecond,None->[cond]|None,Someincr->[incr]|None,None->[]in{exprs;stmts=[init;body]},(function|{exprs;stmts=[init;body]}->letcond,incr=matchcond,incr,exprswith|_,_,[]->None,None|Some_,Some_,[cond;incr]->Somecond,Someincr|Some_,None,[cond]->Somecond,None|None,Some_,[incr]->None,Someincr|_->assertfalsein{stmtwithskind=S_c_for(init,cond,incr,body)}|_->assertfalse)|S_c_break_->leafstmt|S_c_continue_->leafstmt|S_c_return(None,_)->leafstmt|S_c_return(Somee,update)->{exprs=[e];stmts=[]},(function|{exprs=[e]}->{stmtwithskind=S_c_return(Somee,update)}|_->assertfalse)|S_c_goto_->leafstmt|S_c_goto_stabstmt->{exprs=[];stmts=[stmt]},(function|{exprs=[];stmts=[stmt]}->{stmtwithskind=S_c_goto_stabstmt}|_->assertfalse)|S_c_switch(cond,body)->{exprs=[cond];stmts=[body]},(function|{exprs=[cond];stmts=[body]}->{stmtwithskind=S_c_switch(cond,body)}|_->assertfalse)|S_c_label_->leafstmt|S_c_switch_case(cases,update)->{exprs=cases;stmts=[]},(function|{exprs=cases;stmts=[]}->{stmtwithskind=S_c_switch_case(cases,update)}|_->assertfalse)|S_c_switch_default_->leafstmt|S_c_asm_->leafstmt|_->defaultstmt);()