Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ast.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-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/>. *)(* *)(****************************************************************************)(**
Abstract syntax tree for C stubs. It is similar to the CST except:
- predicates are expanded.
- types and variables are resolved using the context of the Clang parser.
- calls to sizeof are resolved using Clang's target information.
- stubs and cases record their locals and assignments.
*)openMopsa_utilsopenMopsa_c_parseropenLocationtypestub={stub_name:string;stub_params:varlist;stub_locals:localwith_rangelist;stub_assigns:assignswith_rangelist;stub_body:sectionlist;stub_range:range;}(** {2 Stub sections} *)(** ***************** *)andsection=|S_caseofcase|S_leafofleafandleaf=|S_localoflocalwith_range|S_assumesofassumeswith_range|S_requiresofrequireswith_range|S_assignsofassignswith_range|S_ensuresofensureswith_range|S_freeoffreewith_range|S_messageofmessagewith_rangeandcase={case_label:string;case_body:leaflist;case_locals:localwith_rangelist;case_assigns:assignswith_rangelist;case_range:range;}(** {2 Leaf sections} *)(** ********************** *)andrequires=formulawith_rangeandensures=formulawith_rangeandassumes=formulawith_rangeandlocal={lvar:var;lval:local_value;}andlocal_value=|L_newofresource|L_callofC_AST.funcwith_range(** function *)*exprwith_rangelist(* arguments *)andassigns={assign_target:exprwith_range;assign_offset:intervallist;}andfree=exprwith_rangeandmessage={message_kind:message_kind;message_body:string;}andmessage_kind=Cst.message_kind=|WARN|UNSOUND(** {2 Expressions} *)(** *=*=*=*=*=*=*=* *)andexpr_kind=|E_topofC_AST.type_qual|E_intofZ.t|E_floatoffloat|E_stringofstring|E_charofint|E_invalid|E_varofvar|E_unopofunop*exprwith_range|E_binopofbinop*exprwith_range*exprwith_range|E_addr_ofofexprwith_range|E_derefofexprwith_range|E_castofC_AST.type_qual*bool(** is it explicit? *)*exprwith_range|E_subscriptofexprwith_range*exprwith_range|E_memberofexprwith_range*int*string|E_arrowofexprwith_range*int*string|E_conditionalofexprwith_range*exprwith_range*exprwith_range|E_builtin_callofbuiltin*exprwith_rangelist|E_raiseofstring|E_returnandexpr={kind:expr_kind;typ:C_AST.type_qual;}andlog_binop=Cst.log_binopandbinop=Cst.binopandunop=Cst.unopandset=|S_intervalofinterval|S_resourceofresourceandinterval={itv_lb:exprwith_range;(** lower bound *)itv_open_lb:bool;(** open lower bound *)itv_ub:exprwith_range;(** upper bound *)itv_open_ub:bool;(** open upper bound *)}andresource=stringandvar=C_AST.variableandbuiltin=Cst.builtin(** {2 Formulas} *)(** ************ *)andformula=|F_exprofexprwith_range|F_boolofbool|F_binopoflog_binop*formulawith_range*formulawith_range|F_notofformulawith_range|F_forallofvar*set*formulawith_range|F_existsofvar*set*formulawith_range|F_inofexprwith_range*set|F_otherwiseofformulawith_range*exprwith_range|F_ifofformulawith_range*formulawith_range*formulawith_range(** {2 Utility functions} *)(** ********************* *)letcompare_varv1v2=Compare.compose[(fun()->comparev1.C_AST.var_unique_namev2.C_AST.var_unique_name);(fun()->comparev1.C_AST.var_uidv2.C_AST.var_uid);]letcompare_resourcer1r2=comparer1r2(** {2 Pretty printers} *)(** ******************* *)openFormatletpp_varfmtv=pp_print_stringfmtv.C_AST.var_org_nameletpp_resource=pp_print_stringletpp_builtin=Cst.pp_builtinletpp_listppsepfmtl=pp_print_list~pp_sep:(funfmt()->fprintffmtsep)ppfmtlletpp_optppfmto=matchowith|None->()|Somex->ppfmtxletrecpp_exprfmtexp=matchexp.content.kindwith|E_top(t)->fprintffmt"⊤(%a)"pp_c_qual_typt|E_intn->Z.pp_printfmtn|E_floatf->pp_print_floatfmtf|E_strings->fprintffmt"\"%s\""s|E_charc->ifc>=32&&c<127thenfprintffmt"'%c'"(Char.chrc)elsefprintffmt"%d"c|E_invalid->fprintffmt"INVALID"|E_varv->pp_varfmtv|E_unop(op,e)->fprintffmt"%a(%a)"pp_unopoppp_expre|E_binop(op,e1,e2)->fprintffmt"(%a) %a (%a)"pp_expre1pp_binopoppp_expre2|E_addr_ofe->fprintffmt"&(%a)"pp_expre|E_derefe->fprintffmt"*(%a)"pp_expre|E_cast(t,explicit,e)->ifexplicitthenfprintffmt"(%a) %a"pp_c_qual_typtpp_expreelsepp_exprfmte|E_subscript(a,i)->fprintffmt"%a[%a]"pp_exprapp_expri|E_member(s,i,f)->fprintffmt"%a.%s"pp_exprsf|E_arrow(p,i,f)->fprintffmt"%a->%s"pp_exprpf|E_conditional(c,e1,e2)->fprintffmt"%a?%a:%a"pp_exprcpp_expre1pp_expre2|E_builtin_call(f,args)->fprintffmt"%a(%a)"pp_builtinf(pp_listpp_expr", ")args|E_return->pp_print_stringfmt"return"|E_raisemsg->fprintffmt"raise(\"%s\")"msgandpp_unop=Cst.pp_unopandpp_binop=Cst.pp_binopandpp_c_qual_typfmtt=Format.pp_print_stringfmt(C_print.string_of_type_qualt)letrecpp_formulafmt(f:formulawith_range)=matchf.contentwith|F_expre->pp_exprfmte|F_booltrue->pp_print_stringfmt"true"|F_boolfalse->pp_print_stringfmt"false"|F_binop(op,f1,f2)->fprintffmt"(%a) %a (%a)"pp_formulaf1pp_log_binopoppp_formulaf2|F_notf->fprintffmt"not (%a)"pp_formulaf|F_forall(x,set,f)->fprintffmt"∀ %a %a ∈ %a: @[%a@]"pp_c_qual_typx.C_AST.var_typepp_varxpp_setsetpp_formulaf|F_exists(x,set,f)->fprintffmt"∃ %a %a ∈ %a: @[%a@]"pp_c_qual_typx.C_AST.var_typepp_varxpp_setsetpp_formulaf|F_in(x,set)->fprintffmt"%a ∈ %a"pp_exprxpp_setset|F_otherwise(f,e)->fprintffmt"%a otherwise %a"pp_formulafpp_expre|F_if(c,f1,f2)->fprintffmt"if %a then %a else %a end"pp_formulacpp_formulaf1pp_formulaf2andpp_log_binop=Cst.pp_log_binopandpp_setfmt=function|S_intervalitv->pp_intervalfmtitv|S_resource(r)->pp_resourcefmtrandpp_intervalfmti=fprintffmt"%s%a, %a%s"(ifi.itv_open_lbthen"]"else"[")pp_expri.itv_lbpp_expri.itv_ub(ifi.itv_open_ubthen"["else"]")letrecpp_localfmtlocal=letlocal=get_contentlocalinfprintffmt"local : %a %a = @[%a@];"pp_c_qual_typlocal.lvar.var_typepp_varlocal.lvarpp_local_valuelocal.lvalandpp_local_valuefmtv=matchvwith|L_newresource->fprintffmt"new %a"pp_resourceresource|L_call(f,args)->fprintffmt"%s(%a)"f.content.func_org_name(pp_listpp_expr", ")argsletpp_requiresfmtrequires=fprintffmt"requires : @[%a@];"pp_formularequires.contentletpp_assignsfmtassigns=fprintffmt"assigns : %a%a;"pp_exprassigns.content.assign_target(pp_print_list~pp_sep:(funfmt()->())pp_interval)assigns.content.assign_offsetletpp_assumesfmt(assumes:assumeswith_range)=fprintffmt"assumes : @[%a@];"pp_formulaassumes.contentletpp_ensuresfmtensures=fprintffmt"ensures : @[%a@];"pp_formulaensures.contentletpp_freefmtfree=fprintffmt"free : %a;"pp_exprfree.contentletpp_messagefmtmsg=matchmsg.content.message_kindwith|WARN->fprintffmt"warn: \"%s\";"msg.content.message_body|UNSOUND->fprintffmt"unsound: \"%s\";"msg.content.message_bodyletpp_leaf_sectionfmtsec=matchsecwith|S_locallocal->pp_localfmtlocal|S_assumesassumes->pp_assumesfmtassumes|S_requiresrequires->pp_requiresfmtrequires|S_assignsassigns->pp_assignsfmtassigns|S_ensuresensures->pp_ensuresfmtensures|S_freefree->pp_freefmtfree|S_messagemsg->pp_messagefmtmsgletpp_leaf_sectionsfmtsecs=pp_print_list~pp_sep:(funfmt()->fprintffmt"@\n")pp_leaf_sectionfmtsecsletpp_casefmtcase=fprintffmt"case \"%s\":@\n @[<v 2>%a@]"case.case_labelpp_leaf_sectionscase.case_bodyletpp_sectionfmtsec=matchsecwith|S_leafleaf->pp_leaf_sectionfmtleaf|S_casecase->pp_casefmtcaseletpp_sectionsfmtsecs=pp_print_list~pp_sep:(funfmt()->fprintffmt"@\n")pp_sectionfmtsecs