예제 #1
0
static TYPE canonicalPtrType(   // GET CANONICAL PTR TYPE
    TYPE type )                 // - type
{
    TYPE test;                  // - used to test type

    test = PointerTypeEquivalent( type );
    if( test == NULL ) {
        type = canonicalBaseType( type );
    } else if( FunctionDeclarationType( test ) ) {
        type = MakePointerTo( canonicalBaseType( test ) );
    } else {
        type = MakePointerTo( canonicalBaseType( test->of ) );
    }
    return type;
}
예제 #2
0
static TYPE makePointerToModType( // MAKE POINTER TO [OPTIONALLY MODIFIED] TYPE
    TYPE type,                  // - base type
    type_flag flags )           // - flags
{
    if( flags != 0 ) {
        type = MakeModifiedType( type, flags );
    }
    return( MakePointerTo( type ) );
}
예제 #3
0
static boolean adjustForVirtualCall( // ADJUSTMENTS FOR POSSIBLE VIRTUAL CALL
    PTREE *this_node,           // - addr[ "this" node ]
    PTREE *routine,             // - routine to be called
    SEARCH_RESULT *result )     // - search result for routine
{
    SYMBOL sym;                 // - symbol for call
    unsigned retn;              // - return: TRUE ==> adjusted for virtual
    TYPE this_type;             // - target type for "this"
    PTREE expr;                 // - transformed expression
    boolean exact_call;         // - TRUE ==> this node is exact

    expr = *this_node;
    this_type = NodeType( expr );
    this_type = StructType( this_type );
    if( this_type != NULL ) {
        if( OMR_CLASS_VAL == ObjModelArgument( this_type ) ) {
            expr = NodeAssignTemporary( this_type, expr );
        } else {
            expr = NodeConvert( MakePointerTo( expr->type ), expr );
        }
        *this_node = expr;
    }
    sym = (*routine)->u.symcg.symbol;
    this_type = TypeThisForCall( expr, sym );
    /* virtual calls don't have to check for NULL pointers when they convert */
    expr->flags |= PTF_PTR_NONZERO;
    exact_call = expr->flags & PTF_MEMORY_EXACT;
    NodeConvertToBasePtr( this_node, this_type, result, TRUE );
    sym = SymDefaultBase( sym );
    if( ( SymIsVirtual( sym ) )
      &&( ! ( (*routine)->flags & PTF_COLON_QUALED ) )
      &&( ! exact_call ) ) {
        expr = AccessVirtualFnAddress( NodeDupExpr( this_node )
                                     , result
                                     , sym );
        expr->type = MakePointerTo( expr->type );
        *routine = NodeReplace( *routine, expr );
        retn = TRUE;
    } else {
        NodeFreeSearchResult( *routine );
        retn = FALSE;
    }
    return( retn );
}
예제 #4
0
static void throwBasePtrCnv(    // CONVERSION TO A PTR. TO BASE CLASS
    SCOPE base,                 // - scope for base class
    void *dat )                 // - control area
{
    THROW_CNV_CTL *ctl;         // - control area

    ctl = dat;
    if( validateBase( base, ctl ) ) {
        makeThrowCnv( ctl, MakePointerTo( ScopeClass( base ) ), ctl->offset );
    }
}
예제 #5
0
TYPE TypeThisForCall(           // GET "THIS" TYPE FOR A CALL
    PTREE this_node,            // - this node
    SYMBOL sym )                // - function being called
{
    TYPE this_type;             // - target type for "this"

    this_type = SymClass( sym );
    if( ExprIsLvalue( this_node ) ) {
        this_type = MakeReferenceTo( this_type );
    } else {
        this_type = MakePointerTo( this_type );
    }
    return( this_type );
}
예제 #6
0
static void genInitFiniReference( // GENERATE INIT/FINI REFERENCE TO FUNCTION
    SYMBOL func,                // - function to be called
    unsigned priority,          // - priority
    NAME name,                  // - name for reference
    fe_seg_id tgt_seg )         // - segment # of target segment
{
    SYMBOL init_ref;            // - reference to mod-init. function
    TYPE type;                  // - used to build type

    SegmentMarkUsed( tgt_seg );
    type = MakePointerTo( func->sym_type );
    init_ref = SymCreateFileScope( type
                                 , SC_STATIC
                                 , SF_INITIALIZED | SF_REFERENCED
                                 , name );
    init_ref->segid = tgt_seg;
    if( tgt_seg == SEG_INIT_REF ) {
        CgFrontInitRef();
    } else {
        CgFrontFiniRef();
    }
    CgFrontDataPtr( IC_DATA_LABEL, init_ref );
    #if _INTEL_CPU
        CgFrontDataPtr( IC_SET_TYPE, GetBasicType( TYP_UCHAR ) );
        if( IsBigCode() ) {
            CgFrontDataInt( IC_DATA_INT, 1 );
        } else {
            CgFrontDataInt( IC_DATA_INT, 0 );
        }
        CgFrontDataInt( IC_DATA_INT, priority );
    #elif _CPU == _AXP
        CgFrontDataPtr( IC_SET_TYPE, GetBasicType( TYP_UINT ) );
        CgFrontDataInt( IC_DATA_INT, 0 );
        CgFrontDataInt( IC_DATA_INT, priority );
    #else
        #error BAD _CPU
    #endif
    CgFrontDataPtr( IC_SET_TYPE, type );
    CgFrontDataInt( IC_DATA_PTR_OFFSET, 0 );
    CgFrontDataPtr( IC_DATA_PTR_SYM, func );
    #if _CPU == 8086
        if( !IsBigCode() ) {
            CgFrontDataInt( IC_DATA_INT, 0 );
        }
    #elif COMP_CFG_COFF == 1
        CgFrontDataPtr( IC_SET_TYPE, GetBasicType( TYP_USHORT ) );
        CgFrontDataInt( IC_DATA_INT, 0 );
    #endif
}
예제 #7
0
static void moduleInitVar(      // GENERATE REFERENCE TO MODULE-INIT VAR.
    SYMBOL var,                 // - variable
    bool base_type )            // - base_type or pointer to it
{
    unsigned offset;            // - offset to be tested
    TYPE type;                  // - type for flags variable

    type = var->sym_type;
    offset = type->u.a.array_size - 1;
    if( offset != 0 ) {
        CgSetType( GetBasicType( TYP_UINT ) );
        CgFrontCodeUint( IC_LEAF_CONST_INT, offset );
        CgFrontSymbol( var );
        CgSetType( MakePointerTo( type->of ) );
        CgFrontCodeUint( IC_OPR_BINARY, CO_PLUS );
    } else {
        CgFrontSymbol( var );
    }
    if( base_type ) {
        CgSetType( type->of );
    } else {
        CgSetType( MakePointerTo( type->of ) );
    }
}
예제 #8
0
TYPE TypeThisSymbol(            // GET TYPE OF THIS FOR SYMBOL MEMBER
    SYMBOL sym,                 // - symbol
    bool reference )            // - use reference?
{
    TYPE base;                  // - return: NULL or TYPE of "this" for symbol
    type_flag flags;            // - flags for "this" pointer

    base = getThisBaseType( sym );
    if( base != NULL ) {
        flags = FunctionThisFlags( sym );
        base = MakeModifiedType( base, flags );
        if( reference ) {
            base = MakeReferenceTo( base );
        } else {
            base = MakePointerTo( base );
        }
        base = MakeModifiedType( base, TF1_CONST );
    }
    return( base );
}
예제 #9
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 );
}
예제 #10
0
bool TypeCompareExclude( TYPE type1, TYPE type2, type_exclude mask )
/******************************************************************/
{
    TC_STATE    state;
    type_flag   flag1;
    type_flag   flag2;
    void        *base1;
    void        *base2;
    TC_DATA     *stack;

    if( type1 == type2 ) {
        return( true );
    }
    stack = NULL;
    state = FOLLOW_OF;
    for(;;) {
        if( type1 == NULL || type2 == NULL ) break;

        // tweak type1 and type2 to ignore minor distinctions
        type1 = TypeModExtract( type1, &flag1, &base1, mask|TC1_NOT_MEM_MODEL );
        type2 = TypeModExtract( type2, &flag2, &base2, mask|TC1_NOT_MEM_MODEL );
        if( type1 == NULL || type2 == NULL ) break;

        if( mask & TC1_PTR_FUN ) {
            type_flag   extra;

            // tweak type1 and type2 to ignore more major distinction
            if( ( type1->id == TYP_POINTER )
              &&( type2->id == TYP_FUNCTION ) ) {
                type2 = TypeModFlagsEC( MakePointerTo( type2 ), &extra );
                flag2 |= extra;
            } else if( ( type2->id == TYP_POINTER )
                     &&( type1->id == TYP_FUNCTION ) ) {
                type1 = TypeModFlagsEC( MakePointerTo( type1 ), &extra );
                flag1 |= extra;
            }
        }

        if( ( type1->id == TYP_CLASS )
         && ( type1->flag & TF1_UNBOUND )
         && ( type1->of != NULL ) ) {
            type1 = type1->of;
        }
        if( ( type2->id == TYP_CLASS )
         && ( type2->flag & TF1_UNBOUND )
         && ( type2->of != NULL ) ) {
            type2 = type2->of;
        }

        // compare type1 and type2
        flag1 &= ~TF1_MOD_IGNORE;
        flag2 &= ~TF1_MOD_IGNORE;
        if( flag1 != flag2 ) {
            break;
        } else if( (flag1 & TF1_BASED) &&
                   !TypeBasesEqual( flag1, base1, base2 ) ) {
            break;
        } else if( type1 == type2 ) {
            state = FOLLOW_STACK;
        } else {
            if( !typeCompareCurrent( &stack, type1, type2, mask ) ) {
                break;
            }
        }

        // advance the type pointers
        for( ; ; ) {
            TC_DATA     *top;
            unsigned    arg_index;

            switch( state ) {
            case FOLLOW_OF:
                type1 = type1->of;
                type2 = type2->of;
                break;
            case FOLLOW_STACK:
                top = stack;
                if( top == NULL ) {
                    return( true );
                }
                state = FOLLOW_OF;
                switch( top->flavour ) {
                case FUNCTION:
                    arg_index = --top->arg_index;
                    type1 = top->type1->u.f.args->type_list[arg_index];
                    type2 = top->type2->u.f.args->type_list[arg_index];
                    mask  = top->mask;
                    if( arg_index == 0 ) {
                        popTC_DATA( &stack );
                    }
                    break;
                case MEMBER_POINTER:
                    type1 = top->type1->u.mp.host;
                    type2 = top->type2->u.mp.host;
                    mask  = top->mask;
                    popTC_DATA( &stack );
                    break;
                }
                break;
            }
            if( type1 == type2 ) {
                state = FOLLOW_STACK;
                continue;
            }
            break;
        }
    }
    while( stack != NULL ) {
        popTC_DATA( &stack );
    }
    return( false );
}
예제 #11
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;
}