PTREE VfnDecorateCall( // DECORATE VIRTUAL CALL PTREE expr, // - call-setup expression SYMBOL vfun ) // - virtual function { PTREE sym; // - node for virtual function call vfun = SymDefaultBase( vfun ); sym = NodeMakeCallee( vfun ); sym->cgop = CO_IGNORE; sym = NodeBinary( CO_VIRT_FUNC, expr, sym ); sym->flags = expr->flags; sym->type = expr->type; return( sym ); }
static boolean adjustForVirtualCall( // ADJUSTMENTS FOR POSSIBLE VIRTUAL CALL PTREE *this_node, // - addr[ "this" node ] PTREE *routine, // - routine to be called SEARCH_RESULT *result ) // - search result for routine { SYMBOL sym; // - symbol for call unsigned retn; // - return: TRUE ==> adjusted for virtual TYPE this_type; // - target type for "this" PTREE expr; // - transformed expression boolean exact_call; // - TRUE ==> this node is exact expr = *this_node; this_type = NodeType( expr ); this_type = StructType( this_type ); if( this_type != NULL ) { if( OMR_CLASS_VAL == ObjModelArgument( this_type ) ) { expr = NodeAssignTemporary( this_type, expr ); } else { expr = NodeConvert( MakePointerTo( expr->type ), expr ); } *this_node = expr; } sym = (*routine)->u.symcg.symbol; this_type = TypeThisForCall( expr, sym ); /* virtual calls don't have to check for NULL pointers when they convert */ expr->flags |= PTF_PTR_NONZERO; exact_call = expr->flags & PTF_MEMORY_EXACT; NodeConvertToBasePtr( this_node, this_type, result, TRUE ); sym = SymDefaultBase( sym ); if( ( SymIsVirtual( sym ) ) &&( ! ( (*routine)->flags & PTF_COLON_QUALED ) ) &&( ! exact_call ) ) { expr = AccessVirtualFnAddress( NodeDupExpr( this_node ) , result , sym ); expr->type = MakePointerTo( expr->type ); *routine = NodeReplace( *routine, expr ); retn = TRUE; } else { NodeFreeSearchResult( *routine ); retn = FALSE; } return( retn ); }
static SYMBOL pickCorrectFunction(// FIND FUNCTION SYMBOL WITH CORRECT # PARMS SYMBOL syms, // - function symbols PTREE expr ) // - call parse tree { unsigned num_args; SYMBOL sym; PTREE arg; num_args = 0; for( arg = expr->u.subtree[1]; arg != NULL; arg = arg->u.subtree[0] ) { ++num_args; } RingIterBeg( syms, sym ) { if( TypeHasNumArgs( sym->sym_type, num_args ) ) { return( sym ); } } RingIterEnd( sym ) return( SymDefaultBase( syms ) ); }
PTREE AccessVirtualFnAddress( // GET ADDRESS OF VIRTUAL FUNCTION PTREE node, // - class pointer SEARCH_RESULT *result, // - access info SYMBOL sym ) // - symbol to access (virtual fun) { SYMBOL vfun; // - virtual function to call thru table SYMBOL base_this; // - basing "this" symbol target_offset_t this_offset;// - offset to "this" basing symbol target_offset_t vf_offset; // - offset to VF PTR vindex vf_index; // - index in VF table vf_offset = result->vf_offset; vfun = SymDefaultBase( sym ); vf_index = vfun->u.member_vf_index - 1; if( NodeGetIbpSymbol( node, &base_this, &this_offset ) ) { node = genVfunIcs( vf_offset, node, vf_index, base_this, vfun ); } else { node = genVfunCall( vf_offset, node, vf_index, sym ); } return( node ); }