PTREE UdcCall // CALL UDC FUNCTION ( PTREE src // - source expression , TYPE udcf_type // - type for udcf , CALL_DIAG* diagnosis ) // - call diagnosis { PTREE node; // - node under construction SEARCH_RESULT* result; // - result for scope diagnosis TYPE class_type; // - class for UDCF class_type = ClassTypeForType( NodeType( src ) ); result = ScopeFindScopedMemberConversion ( class_type->u.c.scope , NULL , udcf_type , TF1_NULL ); node = NodeMakeCallee( result->sym ); node->u.symcg.result = result; node->cgop = CO_NAME_CONVERT; node = NodeDottedFunction( src, node ); node = PTreeCopySrcLocation( node, src ); node = NodeBinary( CO_CALL_NOOVLD, node, NULL ); node = PTreeCopySrcLocation( node, src ); node = AnalyseCall( node, diagnosis ); return node; }
PTREE NodeMakeCall( // FABRICATE A FUNCTION CALL EXPRESSION SYMBOL proc, // - procedure TYPE type, // - return type PTREE args ) // - arguments { DbgVerify( (PointerTypeEquivalent( type ) == NULL) == (PointerTypeEquivalent( SymFuncReturnType( proc ) ) == NULL) , "NodeMakeCall -- return type mismatch" ); return makeCall( NodeMakeCallee( proc ), type, args, TRUE ); }
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 ); }
// When bound, the function is called directly. // // When not bound, // - fetch reference // - add vf_offset // - fetch VFT ptr // - index using vf_index // static PTREE genVfunIcs( // GENERATE IC'S FOR CG-GENERATION OF VFUN CALL target_offset_t vf_offset, // - offset to VF table ptr PTREE node, // - original "this" expression vindex vf_index, // - index into VF table SYMBOL baser, // - basing "this" symbol SYMBOL vfun ) // - virtual function { PTREE expr; // - expression under construction expr = NodeMakeCallee( vfun ); expr->cgop = CO_IGNORE; expr = NodeUnary( CO_CALL_SETUP_VFUN, expr ); expr->type = vfun->sym_type; expr->flags = node->flags; expr = PtdVfunAccess( expr, vf_index, vf_offset, baser ); node = NodeUnaryCopy( CO_VFUN_PTR, node ); return( NodeComma( node, expr ) ); }
// This is kluge because of the lack of a code-generation interface to // signal a virtual function reference. // // This is accomplished by putting out a fake virtual call in dead-code. // void VfnReference( // EMIT VIRTUAL FUNCTION REFERENCE SYMBOL vfun ) // - a virtual function { CGLABEL around; // - label for jump around PTREE fake; // - fake call expression around = CgFrontLabelCs(); CgFrontGotoNear( IC_LABEL_CS, O_GOTO, around ); fake = NodeAssignTemporary( MakePointerTo( vfun->sym_type ) , NodeMakeCallee( vfun ) ); fake = NodeRvalue( fake ); fake = NodeUnaryCopy( CO_CALL_SETUP_IND, fake ); fake = VfnDecorateCall( fake, vfun ); fake = NodeBinary( CO_CALL_EXEC_IND, fake, NULL ); fake->type = SymFuncReturnType( vfun ); fake->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF; fake = NodeDone( fake ); IcEmitExpr( fake ); CgFrontLabdefCs( around ); CgFrontLabfreeCs( 1 ); }
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; } }