/// Generate the CFG for a function. If function_no is None, generate the implicit default
/// constructor
Generate the CFG for a function. If function_no is None, generate the implicit default
constructor
Generate the CFG for a function . If function_no is None generate the implicit default constructor
pub fn generate_cfg(
    contract_no: usize,
    function_no: Option<usize>,
    cfg_no: usize,
    all_cfgs: &mut Vec<ControlFlowGraph>,
    ns: &mut Namespace,
) {
    let default_constructor = &ns.default_constructor(contract_no);
    let func = match function_no {
        Some(function_no) => &ns.functions[function_no],
        None => default_constructor,
    };
    // if the function is a fallback or receive, then don't bother with the overriden functions; they cannot be used
    if func.ty == pt::FunctionTy::Receive {
        // if there is a virtual receive function, and it's not this one, ignore it
        if let Some(receive) = ns.contracts[contract_no].virtual_functions.get("@receive") {
            if Some(*receive) != function_no {
                return;
            }
        }
    }
    if func.ty == pt::FunctionTy::Fallback {
        // if there is a virtual fallback function, and it's not this one, ignore it
        if let Some(fallback) = ns.contracts[contract_no].virtual_functions.get("@fallback") {
            if Some(*fallback) != function_no {
                return;
            }
        }
    }
    if func.ty == pt::FunctionTy::Modifier {
        return;
    }
    let mut cfg = function_cfg(contract_no, function_no, ns);
    // if the function is a modifier, generate the modifier chain
    if !func.modifiers.is_empty() {
        // only function can have modifiers
        assert_eq!(func.ty, pt::FunctionTy::Function);
        let public = cfg.public;
        let nonpayable = cfg.nonpayable;
        cfg.public = false;
        for call in func.modifiers.iter().rev() {
            let modifier_cfg_no = all_cfgs.len();
            all_cfgs.push(cfg);
            let (modifier_no, args) = resolve_modifier_call(call, &ns.contracts[contract_no]);
            let modifier = &ns.functions[modifier_no];
            cfg =
                generate_modifier_dispatch(contract_no, func, modifier, modifier_cfg_no, args, ns);
        }
        cfg.public = public;
        cfg.nonpayable = nonpayable;
        cfg.selector = func.selector();
    }
    reaching_definitions::find(&mut cfg);
    constant_folding::constant_folding(&mut cfg, ns);
    vector_to_slice::vector_to_slice(&mut cfg, ns);
    all_cfgs[cfg_no] = cfg;
}
pub fn generate_cfg ( contract_no : usize , function_no : Option < usize > , cfg_no : usize , all_cfgs : & mut Vec < ControlFlowGraph > , ns : & mut Namespace , ) { let default_constructor = & ns . default_constructor ( contract_no ) ; let func = match function_no { Some ( function_no ) => & ns . functions [ function_no ] , None => default_constructor , } ; // if the function is a fallback or receive, then don't bother with the overriden functions; they cannot be used if func . ty == pt :: FunctionTy :: Receive { // if there is a virtual receive function, and it's not this one, ignore it if let Some ( receive ) = ns . contracts [ contract_no ] . virtual_functions . get ( " " ) { if Some ( * receive ) != function_no { return ; } } } if func . ty == pt :: FunctionTy :: Fallback { // if there is a virtual fallback function, and it's not this one, ignore it if let Some ( fallback ) = ns . contracts [ contract_no ] . virtual_functions . get ( " " ) { if Some ( * fallback ) != function_no { return ; } } } if func . ty == pt :: FunctionTy :: Modifier { return ; } let mut cfg = function_cfg ( contract_no , function_no , ns ) ; // if the function is a modifier, generate the modifier chain if ! func . modifiers . is_empty ( ) { // only function can have modifiers assert_eq ! ( func ty pt FunctionTy Function ) ; let public = cfg . public ; let nonpayable = cfg . nonpayable ; cfg . public = false ; for call in func . modifiers . iter ( ) . rev ( ) { let modifier_cfg_no = all_cfgs . len ( ) ; all_cfgs . push ( cfg ) ; let ( modifier_no , args ) = resolve_modifier_call ( call , & ns . contracts [ contract_no ] ) ; let modifier = & ns . functions [ modifier_no ] ; cfg = generate_modifier_dispatch ( contract_no , func , modifier , modifier_cfg_no , args , ns ) ; } cfg . public = public ; cfg . nonpayable = nonpayable ; cfg . selector = func . selector ( ) ; } reaching_definitions :: find ( & mut cfg ) ; constant_folding :: constant_folding ( & mut cfg , ns ) ; vector_to_slice :: vector_to_slice ( & mut cfg , ns ) ; all_cfgs [ cfg_no ] = cfg ; }
Generate the CFG for a function.
Generate the CFG for a function .
contract_no
usize
function_no
Option<usize>
cfg_no
usize
all_cfgs
&mut Vec<ControlFlowGraph>
ns
&mut Namespace