Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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 );
}
Ejemplo n.º 3
0
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 );
}
Ejemplo n.º 4
0
// 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 ) );
}
Ejemplo n.º 5
0
// 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 );
}
Ejemplo n.º 6
0
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;
    }
}