コード例 #1
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;
}
コード例 #2
0
static boolean passStructOnStack( // PASS A STRUCT/CLASS ON STACK
    PTREE arg,                  // - argument (CO_LIST)
    unsigned warning )          // - internal-data warning
{
    PTREE right;                // - right operand
    TYPE type;                  // - class type

    right = NodeRvalue( arg->u.subtree[1] );
    type = right->type;
    if( right->flags & PTF_CLASS_RVREF ) {
        if( right->op != PT_ERROR ) {
            PTREE temp = NodeTemporary( type );
            right = ClassDefaultCopyDiag( temp, right, &diagEllConv );
            if( right->op != PT_ERROR ) {
                right = NodeDtorExpr( right, temp->u.symcg.symbol );
                if( right->op != PT_ERROR ) {
                    right->type = type;
                    right = NodeFetch( right );
                    right->flags &= ~PTF_LVALUE;
                }
            }
        }
        if( right->op == PT_ERROR ) {
            arg->u.subtree[1] = right;
            PTreeErrorNode( arg );
            return FALSE;
        }
    }
    arg_finish( right, arg );
    if( TypeHasSpecialFields( type ) ) {
        PTreeWarnExpr( arg, warning );
    }
    return TRUE;
}
コード例 #3
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 );
}
コード例 #4
0
static boolean convertEllipsisArg(// CONVERT AN ELLIPSIS (...) ARGUMENT
    PTREE arg )                 // - argument
{
    boolean retn;               // - return: TRUE ==> ok
    PTREE right;                // - argument
    PTREE afun;                 // - &[ function ]
    TYPE type;                  // - node type

    switch( NodeAddrOfFun( PTreeOpRight( arg ), &afun ) ) {
      case ADDR_FN_MANY :
      case ADDR_FN_MANY_USED :
        PTreeErrorExpr( arg->u.subtree[1], ERR_ELLIPSE_ADDR_OVERLOAD );
        retn = FALSE;
        break;
      default :
        right = NodeRvalue( arg->u.subtree[1] );
        arg->u.subtree[1] = right;
        type =  TypedefModifierRemove( right->type );
        switch( type->id ) {
          case TYP_CHAR :
          case TYP_SCHAR :
          case TYP_UCHAR :
          case TYP_SSHORT :
          case TYP_WCHAR :
          case TYP_USHORT :
            type = TypeUnArithResult( type );
            right = NodeConvert( type, right );
            arg_finish( right, arg );
            retn = TRUE;
            break;
          case TYP_FLOAT :
            type = GetBasicType( TYP_DOUBLE );
            right = NodeConvert( type, right );
            arg_finish( right, arg );
            retn = TRUE;
            break;
          case TYP_ARRAY :
            type = PointerTypeForArray( right->type );
            right = NodeConvert( type, right );
            arg_finish( right, arg );
            retn = TRUE;
            break;
          case TYP_MEMBER_POINTER :
            ConvertMembPtrConst( &arg->u.subtree[1] );
            arg_fillout( arg );
            retn = TRUE;
            break;
          case TYP_POINTER :
            if( NULL == FunctionDeclarationType( type->of ) ) {
                type_flag def_flags;
                type_flag act_flags;
                type_flag arg_flags;
                TYPE base_type;
                PTREE cnv;
                base_type = TypeGetActualFlags( type->of, &arg_flags );
                act_flags = arg_flags & TF1_MEM_MODEL;
                def_flags = DefaultMemoryFlag( type->of );
                if( ( ( def_flags & TF1_FAR )
                    &&( act_flags != TF1_HUGE )
                    &&( act_flags != TF1_FAR ) )
                  ||( ( def_flags & TF1_HUGE )
                    &&( act_flags != TF1_HUGE ) )
                  ) {
                    type = MakeModifiedType( base_type
                                           , ( arg_flags
                                             & ~TF1_MEM_MODEL )
                                           | def_flags );
                    type = MakePointerTo( type );
                    cnv = CastImplicit( arg->u.subtree[1]
                                      , type
                                      , CNV_EXPR
                                      , NULL );
                    arg->u.subtree[1] = cnv;
                    DbgVerify( PT_ERROR != cnv->op
                             , "convertEllipsisArg -- failed ptr.cnv" );
                    arg_fillout( arg );
                    retn = TRUE;
                } else {
                    arg_fillout( arg );
                    retn = TRUE;
                }
            } else {
                arg_fillout( arg );
                retn = TRUE;
            }
            break;
          case TYP_CLASS :
            retn = passStructOnStack( arg, WARN_ELLIPSIS_CLASS_ARG );
            break;
          default :
            arg_fillout( arg );
            retn = TRUE;
            break;
        }
        break;
    }
    return retn;
}