cgbkutil.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,074 行 · 第 1/3 页

C
1,074
字号
    SYMBOL dtor,                // - destructor
    cg_name var,                // - expression to be DTOR'ed
    unsigned cdtor )            // - CDTOR to be used
{
    call_handle handle;         // - call handle

    handle = initDtorCall( dtor );
    addDtorArgs( handle, dtor, var, cdtor );
    return finiDtorCall( handle, cdtor );
}


static cg_name cgCommaSideEffect( // CONSTRUCT COMMA/SIDE-EFFECT EXPRESSION
    cg_name lhs,                // - expression on left
    cg_name rhs,                // - expression on right
    cg_type type,               // - type of right expression
    cg_op opcode )              // - type of opcode
{
    cg_name expr;               // - result
    if( NULL == lhs ) {
        expr = rhs;
    } else if( NULL == rhs ) {
        expr = lhs;
    } else {
        expr = CGBinary( opcode, lhs, rhs, type );
    }
    return expr;
}


cg_name CgComma(                // CONSTRUCT COMMA EXPRESSION
    cg_name lhs,                // - expression on left
    cg_name rhs,                // - expression on right
    cg_type type )              // - type of right expression
{
    return cgCommaSideEffect( lhs, rhs, type, O_COMMA );
}


void CgCommaWithTopExpr(        // PUSH COMMA'D EXPRESSION WITH TOP EXPR
    cg_name expr,               // - rhs expression
    cg_type type )              // - rhs type
{
    cg_name lhs;                // - lhs expression

    if( CgExprPopGarbage() ) {
        lhs = NULL;
    } else {
        lhs = CgExprPop();
    }
    CgExprPush( CgComma( lhs, expr, type ), type );
}


cg_name CgSideEffect(           // CONSTRUCT SIDE-EFFECT EXPRESSION
    cg_name lhs,                // - expression on left
    cg_name rhs,                // - expression on right
    cg_type type )              // - type of right expression
{
#if 0
    return cgCommaSideEffect( lhs, rhs, type, O_SIDE_EFFECT );
#else
    cg_name expr;               // - result
    if( NULL == lhs ) {
        expr = rhs;
    } else if( NULL == rhs ) {
        expr = lhs;
    } else {
        temp_handle handle;     // - handle
        expr = CgSaveAsTemp( &handle, lhs, type );
        expr = CgComma( expr, rhs, type );
        expr = CgComma( expr, CgFetchTemp( handle, type ), type );
    }
    return expr;
#endif
}


// when expr is non-null, top of stack is replaced by:
//
//                      COMMA
//                       | |
//             +---------+ +-------+
//             |                   |
//           COMMA               temp
//            | |
//       +----+ +----+
//       |           |
//    ASSIGN        expr
//      | |
//    +-+ +-+
//    |     |
//  temp   top
//
void CgCommaOptional(           // EMIT OPTIONAL COMMA'ED EXPRESSION
    cg_name expr,               // - expression or NULL
    cg_type type )              // - type of expression
{
    cg_name orig;               // - original expression
    cg_type orig_type;          // - original expression type

    if( expr != NULL ) {
        if( ! CgExprPopGarbage() ) {
            orig = CgExprPopType( &orig_type );
            expr = CgSideEffect( orig, expr, type );
        }
        CgExprPush( expr, type );
    }
}


void CgCommaBefore(             // EMIT COMMA'ED EXPRESSION BEFORE
    cg_name expr,               // - expression
    cg_type type )              // - type of above expression
{
    cg_name top_expr;           // - expression on top
    cg_type top_type;           // - type on top

    top_expr = CgExprPopType( &top_type );
    if( top_expr == NULL ) {
        if( expr != NULL ) {
            CgDone( expr, type );
        }
    } else {
        CgExprPush( CgComma( expr, top_expr, top_type ), top_type );
    }
}


SYMBOL CgBackOpDelete(          // GET ADDRESIBLE OPERATOR DELETE FOR A TYPE
    TYPE type )                 // - the type
{
    SEARCH_RESULT* result;      // - lookup result
    SYMBOL op_del;              // - operator delete

    result = ScopeFindNaked( TypeScope( type )
                           , CppOperatorName( CO_DELETE ) );
    op_del = ClassFunMakeAddressable( result->sym_name->name_syms );
    ScopeFreeResult( result );
    return op_del;
}


cg_name CgAssignStateVar(       // ASSIGN STATE-VAR VALUE
    SYMBOL blk,                 // - R/W Block
    SE* se,                     // - state entry
    target_offset_t offset )    // - offset of state variable
{
    return CGLVAssign( CgSymbolPlusOffset( blk, offset )
                     , CgOffset( SeStateVar( se ) )
                     , CgTypeOffset() );
}



//***********************************************************************
// Code Generation Support -- run-time calls
//***********************************************************************

void CgRtCallInit(              // SET UP A R/T CALL
    RT_DEF *def,                // - definition for call
    RTF rt_code )               // - code for run/time call
{
    SYMBOL sym;                 // - symbol for run/time call

    sym = RunTimeCallSymbol( rt_code );
    def->type = CgTypeOutput( SymFuncReturnType( sym ) );
    def->handle = CGInitCall( CgSymbol( sym )
                            , def->type
                            , (cg_sym_handle)sym );
}


void CgRtParam(                 // SET UP A PARAMETER
    cg_name expr,               // - expression gen'ed
    RT_DEF *def,                // - definition for call
    cg_type type )              // - argument type
{
    addArgument( def->handle, expr, type );
}


void CgRtParamConstOffset(      // SET UP PARAMETER: CONSTANT OFFSET
    RT_DEF *def,                // - definition for call
    unsigned value )            // - parameter value
{
    CgRtParam( CgOffset( value ), def, CgTypeOffset() );
}


void CgRtParamAddrSym(          // SET UP PARAMETER: ADDR( SYMBOL )
    RT_DEF *def,                // - definition for call
    SYMBOL sym )                // - symbol
{
    CgRtParam( CgAddrSymbol( sym ), def, T_POINTER );
}


cg_name CgRtCallExec(           // EXECUTE R/T CALL
    RT_DEF *def )               // - definition for call
{
    CgBackCallGened( def->handle );
    return CgFetchType( CGCall( def->handle ), def->type );
}


void CgRtCallExecDone(          // EXECUTE R/T CALL, THEN DONE
    RT_DEF *def )               // - definition for call
{
    CgDone( CgRtCallExec( def ), def->type );
}


void CgRtCallExecNoArgs(        // EXECUTE R/T CALL, WITHOUT ARGUMENTS
    RTF rt_code )               // - code for run/time call
{
    RT_DEF def;                 // - call definition

    CgRtCallInit( &def, rt_code );
    CgRtCallExecDone( &def );
}



//***********************************************************************
// General support
//***********************************************************************


cg_name CgDtorStatic(           // DTOR STATIC OBJECT
    SYMBOL sym )                // - object symbol
{
    STAB_CTL sctl;              // - state-table instance
    STAB_DEFN dctl;             // - state-table definition
    RT_DEF def;                 // - control for run-time call
    SE* se;                     // - state entry

    StabCtlInit( &sctl, &dctl );
    StabDefnInit( &dctl, DTRG_STATIC_INITLS );
#ifndef NDEBUG
    if( PragDbgToggle.dump_stab ) {
        printf( "State Table for static object: %x\n", &dctl.state_table );
    }
#endif
    sctl.rw = CgVarRw( CgbkInfo.size_rw_base + CgbkInfo.size_data_ptr
                     , SC_STATIC );
    dctl.ro = CgVarRo( 1, SC_STATIC, NULL );
    se = SeAlloc( DTC_SYM_STATIC );
    se->base.gen = TRUE;
    se->sym_static.sym = sym;
    se->sym_static.dtor = RoDtorFind( sym );
    se = StateTableAdd( se, &sctl );
    StabGenerate( &sctl );
    CgBackGenLabelInternal( sctl.rw );
    DgInitBytes( CgbkInfo.size_data_ptr, 0 );
    DgPtrSymData( dctl.ro );
    DgOffset( 1 );
    DgPtrSymData( sym );
    CgRtCallInit( &def, RTF_REG_LCL );
    CgRtParamAddrSym( &def, sctl.rw );
    return CgRtCallExec( &def );
}


void CgDtorAll(                 // DTOR ALL IN FUNCTION
    void )
{
    RT_DEF def;                 // - call definition

    CgRtCallInit( &def, RTF_DTOR_ALL );
#if _CPU == _AXP
    CgRtParamAddrSym( &def, FstabExcRw() );
#endif
    CgRtCallExecDone( &def );
}


void CgDtorSe(                  // DTOR UNTIL SE ENTRY
    SE* bound )                 // - bounding entry
{
    RT_DEF def;                 // - call definition

    CgRtCallInit( &def, RTF_DTOR );
    CgRtParamConstOffset( &def, SeStateOptimal( bound ) );
#if _CPU == _AXP
    CgRtParamAddrSym( &def, FstabExcRw() );
#endif
    CgRtCallExecDone( &def );
}


#if _CPU == 386

back_handle CgProfData( void )
/****************************/
{
    FN_CTL *top;

    top = FnCtlTop();
    return( top->prof_data );
}

#endif

// The following can be extended for more types, if required
//
TYPE TypeFromCgType(            // GET C++ TYPE FOR cg_type
    cg_type cgtype )            // - code-gen type
{
    TYPE type;                  // - C++ type

    switch( cgtype ) {
      case T_UINT_1 :
        type = GetBasicType( TYP_UCHAR );
        break;
      case T_INT_1 :
        type = GetBasicType( TYP_SCHAR );
        break;
      case T_UINT_2 :
        type = GetBasicType( TYP_USHORT );
        break;
      case T_INT_2 :
        type = GetBasicType( TYP_SSHORT );
        break;
      case T_UINT_4 :
      #if( TARGET_INT == 4 )
        type = GetBasicType( TYP_UINT );
      #else
        type = GetBasicType( TYP_ULONG );
      #endif
        break;
      case T_INT_4 :
      #if( TARGET_INT == 4 )
        type = GetBasicType( TYP_SINT );
      #else
        type = GetBasicType( TYP_SLONG );
      #endif
        break;
      case T_INT_8 :
        type = GetBasicType( TYP_SLONG64 );
        break;
      case T_UINT_8 :
        type = GetBasicType( TYP_ULONG64 );
        break;
      case T_BOOLEAN :
      case T_INTEGER :
        type = GetBasicType( TYP_SINT );
        break;
      case TY_UNSIGNED :
        type = GetBasicType( TYP_UINT );
        break;
      default :
        type = MakeInternalType( BETypeLength( cgtype ) );
        break;
    }
    return type;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?