コード例 #1
0
PTREE NodeConvertVirtualPtr(    // EXECUTE A VIRTUAL BASE CAST
    PTREE expr,                 // - expr to cast
    TYPE final_type,            // - final type after cast
    target_offset_t vb_offset,  // - offset of vbptr
    vindex vb_index )           // - index in vbtable
{
    PTREE offset;
    TYPE vbptr_type;
    TYPE adjust_type;
    PTREE dup;

    vbptr_type = MakeVBTableFieldType( true );
    offset = NodeOffset( vb_offset );
    expr = NodeBinary( CO_DOT, expr, offset );
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr->type = vbptr_type;
    dup = NodeDupExpr( &expr );
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr = NodeFetch( expr );
    expr->type = vbptr_type;
    expr->flags &= ~ PTF_LVALUE;
    expr->flags |= PTF_PTR_NONZERO;
    adjust_type = TypePointedAtModified( vbptr_type );
    offset = NodeOffset( vb_index * CgMemorySize( adjust_type ) );
    expr = NodeBinary( CO_DOT, expr, offset );
    expr->type = adjust_type;
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr = NodeFetch( expr );
    expr->type = adjust_type;
    expr->flags |= PTF_PTR_NONZERO;
    expr = NodeBinary( CO_DOT, dup, expr );
    expr->type = final_type;
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    return( expr );
}
コード例 #2
0
static PTREE genVfunCall(       // DIRECTLY GENERATE VFUN CALL
    target_offset_t vf_offset,  // - offset to VF table ptr
    PTREE node,                 // - original "this" expression
    target_offset_t vf_index,   // - index into VF table
    SYMBOL sym )                // - symbol to access
{
    TYPE vfptr_type;            // - type[ ptr to VF table ]
    TYPE vfn_type;              // - type[ ptr to VF ]

    node = NodeBinary( CO_DOT, node, NodeOffset( vf_offset ) );
    vfptr_type = MakeVFTableFieldType( TRUE );
    node->type = vfptr_type;
    node->flags |= PTF_LVALUE;
    node = PtdExprConst( node );
    node = NodeRvalue( node );
    vfn_type = TypePointedAtModified( vfptr_type );
    node = NodeBinary( CO_DOT
                     , node
                     , NodeOffset( vf_index * CgMemorySize( vfn_type ) ) );
    node->type = vfn_type;
    node->flags |= PTF_LVALUE;
    node = NodeRvalue( node );
    node->type = sym->sym_type;
    return node;
}
コード例 #3
0
static PTREE adjust_base_ptr(   // ADJUST BASE PTR AS true/TESTING CONVERSION
    PTREE orig,                 // - original node
    PTREE offset,               // - offset calculation
    TYPE type )                 // - type, after conversion
{
    if( orig->flags & PTF_PTR_NONZERO ) {
        orig = NodeBinary( CO_DOT, orig, offset );
    } else {
        orig = NodeBinary( CO_PTR_DELTA, orig, offset );
    }
    orig->type = type;
    return( orig );
}
コード例 #4
0
ファイル: analudc.c プロジェクト: Azarien/open-watcom-v2
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;
}
コード例 #5
0
static PTREE makeCall(          // MAKE A CALL OR INDIRECT CALL
    PTREE proc,                 // - procedure
    TYPE type,                  // - return type
    PTREE args,                 // - arguments
    boolean direct_call )       // - TRUE ==> do a direct call
{
    PTREE node;                 // - new node

    if( direct_call ) {
        node = NodeUnaryCopy( CO_CALL_SETUP, proc );
        node = NodeBinary( CO_CALL_EXEC, node, args );
    } else {
        node = VfunSetupCall( proc );
        node = NodeBinary( CO_CALL_EXEC_IND, node, args );
    }
    return NodeSetType( node, type, PTF_MEANINGFUL | PTF_SIDE_EFF );
}
コード例 #6
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 );
}
コード例 #7
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 );
}
コード例 #8
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;
    }
}
コード例 #9
0
static PTREE transformVaStart   // TRANSFORM TO CO_VASTART OPCODE
    ( PTREE expr )              // - va_start expression
{
    SYMBOL pre_ellipsis_sym;
    SYMBOL stop;
    SYMBOL curr;
    SYMBOL fn;
    SCOPE caller_arg_scope;
    unsigned offset;
    target_size_t arg_size;
    PTREE arg1;
    PTREE arg2;
    PTREE arg3;
    PTREE valist;

    // second argument -- must be pre-... parameter
    arg1 = expr->u.subtree[1];
    arg2 = arg1->u.subtree[0];
    arg3 = arg2->u.subtree[0];
    pre_ellipsis_sym = PTreeOp( &arg2->u.subtree[1] )->u.symcg.symbol;
    caller_arg_scope = ScopeFunctionScopeInProgress();
    fn = ScopeFunction( caller_arg_scope );
    offset = 0;
    if( ObjModelFunctionReturn( fn->sym_type ) == OMR_CLASS_VAL ) {
        offset += TARGET_PACKING;
    }
    if( SymIsThisMember( fn ) ) {
        offset += TARGET_PACKING;
        if( SymCDtorExtraParm( fn ) ) {
            offset += TARGET_PACKING;
        }
    }
    stop = ScopeOrderedStart( caller_arg_scope );
    curr = NULL;
    for(;;) {
        curr = ScopeOrderedNext( stop, curr );
        if( curr == NULL ) {
            PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL );
            return( expr );
        }
        if( ObjModelArgument( curr->sym_type ) == OMR_CLASS_REF ) {
            arg_size = TARGET_PACKING;
        } else {
            arg_size = CgMemorySize( curr->sym_type );
            arg_size += TARGET_PACKING - 1;
            arg_size &= ~( TARGET_PACKING - 1 );
        }
        offset += arg_size;
        if( curr == pre_ellipsis_sym ) break;
    }
    if( ScopeOrderedNext( stop, curr ) != NULL ) {
        PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL );
        return( expr );
    }
    // third argument -- va_list symbol
    valist = arg1->u.subtree[1];
    arg1->u.subtree[1] = NULL;
    if( arg3->u.subtree[1]->u.int_constant == 0 ) {
        // compensate for "void *__alist;" arg in <varargs.h>
        offset -= TARGET_PACKING;
    }
    NodeFreeDupedExpr( expr );
    expr = NodeBinary( CO_VASTART, valist, NodeOffset( offset ) );
    return expr;
}