cgbkibrp.c

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

C
590
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"

#include <float.h>

#include "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "cgbackut.h"
#include "ring.h"
#include "initdefs.h"

#ifndef NDEBUG
    #include "errdefns.h"
#endif

typedef struct ibrp IBRP;
struct ibrp                     // IBRP -- inline bound reference parameters
{   IBRP *next;                 // - next in ring
    cg_name handle;             // - handle of called function
    SYMBOL func;                // - inline function called
    SYMBOL refed;               // - referenced symbol (caller)
    target_size_t offset;       // - offset added to reference arg
    FN_CTL *source;             // - handle of generator of IBRPs
    union {
        unsigned index;         // - argument # (before inlining)
        SYMBOL parm;            // - symbol (after IC_FUNCTION_ARGS)
    } u;
};


static carve_t carveIBRP;           // allocations for IBRPs
static IBRP *ibrps;                 // ring of IBRPs scheduled
static unsigned parm_no;            // parm # being defined


#ifdef NDEBUG
    #define dump_ibrp( ibrp, text )
#else
    #include <stdio.h>
    #include "dbg.h"
    #include "pragdefn.h"

    static void prt_ibrp(           // PRINT IBRP ENTRY
        IBRP* ibrp,                 // - entry
        const char *text )          // - text string
    {
        printf ( "[%x]%s\n    hdl=%x func=%x refed=%x off=%x parm=%x\n"
               , ibrp
               , text
               , ibrp->handle
               , ibrp->func
               , ibrp->refed
               , ibrp->offset
               , ibrp->u.parm );
    }

    static void dump_ibrp(          // DUMP IBRP ENTRY
        IBRP* ibrp,                 // - entry
        const char *text )          // - text string
    {
        if( PragDbgToggle.dump_exec_ic ) {
            prt_ibrp( ibrp, text );
        }
    }

    boolean IbpEmpty(               // DEBUG -- verify empty
        void )
    {
        return ibrps == NULL;
    }

    void IbpDump()                  // DEBUG -- dump all entries
    {
        if( IbpEmpty() ) {
            printf( "IBRP -- no bound references\n" );
        } else {
            IBRP* curr;
            RingIterBeg( ibrps, curr ) {
                prt_ibrp( curr, "IBRP" );
            } RingIterEnd( curr )
        }
    }
#endif


static void ibpRemove(          // REMOVE AN IBRP ENTRY
    IBRP *ibrp )                // - item to be removed
{
    dump_ibrp( ibrp, "IBRP(popped)" );
    RingPrune( &ibrps, ibrp );
    CarveFree( carveIBRP, ibrp );
}


void IbpFlush(                  // REMOVE ALL IBRP ENTRIES FOR THIS CALL CONTEXT
    FN_CTL* fctl )              // - current file control
{
    IBRP *ibrp;                 // - current reference

    RingIterBegSafe( ibrps, ibrp ) {
        if( ibrp->source == fctl ) {
            ibpRemove( ibrp );
        }
    } RingIterEndSafe( ibrp )
}


void IbpAdd(                    // ADD AN IBRP ENTRY
    SYMBOL binding,             // - symbol to bind reference to
    target_offset_t offset,     // - offset into symbol
    FN_CTL* fctl )              // - current file information
{
    IBRP *ibrp;                 // - new entry
    SYMBOL trans;               // - translated symbol
    SYMBOL bound;               // - bound reference
    target_offset_t bound_off;  // - bound offset

    if( SymIsArgument( binding ) ) {
        IbpReference( binding, &trans, &bound, &bound_off );
        trans = bound;
        offset += bound_off;
    } else {
        trans = SymTrans( binding );
    }
    ibrp = RingCarveAlloc( carveIBRP, &ibrps );
    ibrp->handle = CallStackTopHandle();
    ibrp->func = CallStackTopFunction();
    ibrp->refed = trans;
    ibrp->offset = offset;
    ibrp->source = fctl;
    ibrp->u.index = 0;
    dump_ibrp( ibrp, "IBRP(created)" );
}


void IbpDefineSym(              // DEFINE SYMBOL FOR BOUND PARAMETER
    call_handle handle,         // - handle for call
    SYMBOL sym )                // - the symbol
{
    IBRP *ibrp;                 // - current inline bound reference parameter

    if( handle != NULL ) {
        RingIterBeg( ibrps, ibrp ) {
            if( ( handle == ibrp->handle )
              &&( parm_no == ibrp->u.index ) ) {
                ibrp->u.parm = sym;
                dump_ibrp( ibrp, "IBRP(defined parm)" );
                break;
            }
        } RingIterEnd( ibrp )
        ++parm_no;
    }
}


void IbpDefineOffset(           // DEFINE OFFSET FOR BOUND REFERENCE PARAMETER
    target_offset_t offset )    // - the offset
{
    IBRP *ibrp;                 // - current IBRP

    ibrp = ibrps;
    if( ibrp->refed != NULL ) {
        ibrp->offset += offset;
        dump_ibrp( ibrp, "IBRP(defined offset)" );
    }
}


void IbpDefineParms(            // START DEFINING PARAMETERS
    void )
{
    parm_no = 0;
}


void IbpDefineIndex(            // DEFINE CURRENT PARAMETER INDEX
    unsigned index )            // - index
{
    IBRP *ibrp;                 // - current IBRP

    ibrp = ibrps;
    if( ibrp->refed == NULL ) {
        ibpRemove( ibrp );
    } else {
        ibrp->u.index = index;
        dump_ibrp( ibrp, "IBRP(defined index)" );
    }
}


boolean IbpReference(           // LOCATE A BOUND REFERENCE
    SYMBOL sym,                 // - original symbol
    SYMBOL *trans,              // - addr[ translated symbol ]
    SYMBOL *bound,              // - addr[ bound reference ]
    target_offset_t *offset )   // - addr[ offset from bound reference ]
{
    IBRP *ibrp;                 // - current inline bound reference parm.
    boolean retn;               // - TRUE ==> bound was located
    FN_CTL* fctl;               // - current file control

    fctl = FnCtlTop();
    if( sym == NULL ) {
        sym = fctl->this_sym;
    } else {
        sym = SymTrans( sym );
    }
    *trans = sym;
    *bound = NULL;
    *offset = 0;
    retn = FALSE;
    RingIterBeg( ibrps, ibrp ) {
        if( ( sym == ibrp->u.parm )
          &&( fctl->handle == ibrp->handle ) ) {
            *bound = ibrp->refed;
            *offset = ibrp->offset;
            dump_ibrp( ibrp, "IBRP(used)" );
#if 0
            if( PragDbgToggle.dump_exec_ic ) {
                printf( "ibrp->func: " );
                DumpSymbol( ibrp->func );
                printf( "ibrp->refed: " );
                DumpSymbol( ibrp->refed );
                printf( "ibrp->u.parm: " );
                DumpSymbol( ibrp->u.parm );
            }
#endif
            retn = TRUE;
            break;
        }
    } RingIterEnd( ibrp )
    return retn;
}


static cg_name directRef(       // DO DIRECT REFERENCE IF POSSIBLE
    SYMBOL orig_sym,            // - original symbol
    SYMBOL* a_sym,              // - addr[ translated symbol ]
    target_offset_t ref_off )   // - offset to item
{
    SYMBOL bound;               // - bound reference
    target_offset_t offset;     // - offset from bound reference
    cg_name op;                 // - NULL or direct-ref expression

    ref_off = ref_off;
    if( IbpReference( orig_sym, a_sym, &bound, &offset ) ) {
        op = CgSymbolPlusOffset( bound, offset );
    } else {
        op = NULL;
    }
    return op;
}


cg_name IbpFetchRef(            // FETCH A REFERENCE PARAMETER
    SYMBOL orig_sym )           // - NULL or original symbol
{
    SYMBOL sym;                 // - current symbol
    cg_name op;                 // - operand

    op = directRef( orig_sym, &sym, 0 );
    if( NULL == op ) {
        op = CgFetchType( CgSymbol( sym ), CgGetCgType( sym->sym_type ) );
    }

⌨️ 快捷键说明

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