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 ); }
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; } }