static PTREE doCopySubstitution( // EFFECT COPY SUBSTITUTION PTREE* a_repl, // - addr[ temporary to be replaced ] PTREE orig, // - addr[ original node ] PTREE tgt, // - target PTREE dtor ) // - NULL or CO_DTOR node on right { PTREE repl; // - temporary to be replaced repl = NodeRemoveCastsCommas( *a_repl ); DbgVerify( repl->op == PT_SYMBOL, "doCopySubstitution -- not symbol" ); DbgVerify( SymIsTemporary( repl->u.symcg.symbol ) , "doCopySubstitution -- not temporary" ); if( dtor != NULL ) { PTREE old = orig; DbgVerify( dtor->u.subtree[0]->u.symcg.symbol == repl->u.symcg.symbol , "doCopySubstitution -- not same temporary" ); orig = dtor->u.subtree[1]; dtor->u.subtree[1] = NULL; NodeFreeDupedExpr( old ); } repl->u.symcg.symbol->flag = 0; *a_repl = NodeReplace( *a_repl, tgt ); orig = NodeConvertFlags( ClassTypeForType( tgt->type ) , orig , PTF_LVALUE | PTF_MEMORY_EXACT | PTF_SIDE_EFF | PTF_MEANINGFUL ); return orig; }
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 ); }
void NodeConvertToBasePtr( // CONVERT TO A BASE PTR, USING SEARCH_RESULT PTREE *a_expr, // - addr( ptr to be converted ) TYPE base, // - base type SEARCH_RESULT *result, // - search result bool positive ) // - true ==> use positive value { target_offset_t vb_offset; // - offset of vbptr vindex vb_index; // - index in vbtable target_offset_t delta; // - delta for class PTREE node; // - new node PTREE dup; // - node containing duplicate of original PTREE orig; // - original value TYPE ref_type; // - reference type for original value node = *a_expr; /* references can never be NULL by definition */ ref_type = TypeReference( NodeType( node ) ); if( ref_type != NULL ) { node->flags |= PTF_PTR_NONZERO; } if( node->flags & PTF_MEMORY_EXACT ) { adjust_by_delta( a_expr, base, result->exact_delta, positive ); } else if( result->non_virtual ) { adjust_by_delta( a_expr, base, result->delta, positive ); } else { PTF_FLAG orig_prop; // - flags propogated from original SYMBOL ibp; // - inline bound reference parameter target_offset_t offset; // - offset to ibp #if 0 orig_prop = ( node->flags & PTF_FETCH ) | PTF_LVALUE; #else orig_prop = node->flags & PTF_FETCH; if( NULL != ref_type ) { orig_prop |= PTF_LVALUE; } #endif if( NodeGetIbpSymbol( node, &ibp, &offset ) ) { PTREE expr; // - expression under construction unsigned vb_exact; // - exact offset for conversion vb_exact = result->exact_delta; if( ! positive ) { vb_exact = - vb_exact; } vb_exact += offset; if( NULL == ibp ) { expr = NULL; } else { expr = NodeMakeCallee( ibp ); expr->cgop = CO_IGNORE; } expr = NodeUnary( CO_VBASE_FETCH, expr ); expr = PtdVbaseFetch( expr , result->vb_offset , result->vb_index , result->delta + offset , vb_exact ); expr->type = base; expr->flags = orig_prop; node = NodeReplace( node, expr ); } else { dup = NULL; if( ! NodePtrNonZero( node ) ) { dup = NodeDupExpr( &node ); } vb_offset = result->vb_offset; vb_index = result->vb_index; node = NodeConvertVirtualPtr( node, base, vb_offset, vb_index ); delta = result->delta; if( delta != 0 ) { node = NodeBinary( CO_DOT, node, NodeOffset( delta ) ); node->type = base; node->flags |= orig_prop; } if( dup != NULL ) { orig = NodeDupExpr( &dup ); node = NodeTestExpr( NodeCompareToZero( orig ), node, dup ); } } *a_expr = node; } if( ref_type != NULL ) { (*a_expr)->flags |= PTF_LVALUE; } }