icemit.c

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

C
955
字号
/****************************************************************************
*
*                            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 <stddef.h>

#include "memmgr.h"
#include "stringl.h"
#include "ptree.h"
#include "carve.h"
#include "cgfront.h"
#include "dbg.h"
#include "toggle.h"
#include "conpool.h"
#include "label.h"
#include "errdefns.h"
#include "codegen.h"
#include "fnbody.h"
#include "pragdefn.h"
#include "rtfuns.h"
#include "specfuns.h"
#include "objmodel.h"

static TOKEN_LOCN posn_gened;   // source position -- generated
static SYMBOL init_ref_temp;    // temp used for auto initialization of refer.


static void generateScopeCall(  // GENERATE SCOPE CALL FOR DIRECT CALL
    PTREE call_expr )           // - call expression
{
    SYMBOL callee;              // - symbol called
    PTREE call_node;            // - original node

    call_node = call_expr;
    call_expr = call_expr->u.subtree[0];
    if( NodeIsUnaryOp( call_expr, CO_CALL_SETUP ) ) {
        call_expr = PTreeOpLeft( call_expr );
        DbgVerify( call_expr->op == PT_SYMBOL
                 , "generateScopeCall -- not symbol" );
        callee = call_expr->u.symcg.symbol;
        if( SPFN_LONGJMP == SpecialFunction( callee ) ) {
            FunctionCouldThrow( call_node );
        } else {
            FunctionCalled( call_node, callee );
            if( ! SymIsCtor( callee )
             && ! SymIsThunkCtorCopy( callee )
             && ! SymIsThunkCtorDflt( callee ) ) {
                TYPE type = SymFuncReturnType( callee );
                call_expr = PtdCtoredExprType( call_node, callee, type );
            }
        }
    } else {
        FunctionCouldThrow( call_node );
    }
}


static void generate_type(      // GENERATE TYPE FOR A NODE
    PTREE node )                // - current node
{
    if( node->flags & PTF_LVALUE ) {
        CgSetTypeExact( node->type );
    } else {
        if( node->flags & PTF_CLASS_RVREF ) {
            CgSetTypeExact( MakeReferenceTo( node->type ) );
        } else {
            CgSetTypeExact( node->type );
        }
    }
}


static TYPE generate_node_type( // GENERATE EXACT TYPE FOR NODE
    PTREE node )                // - current node
{
    TYPE type;

    if( node->flags & PTF_LVALUE ) {
        type = NodeType( node );
    } else {
        if( node->flags & PTF_CLASS_RVREF ) {
            type = MakeReferenceTo( node->type );
        } else {
            type = node->type;
        }
    }
    CgSetTypeExact( type );
    return( type );
}


static void generate_type_instr(// GENERATE TYPE, INSTRUCTION
    TYPE type,                  // - type generated
    unsigned value,             // - value for ic instruction
    CGOP opcode )               // - opcode
{
    CgSetType( type );
    CgFrontCodeUint( opcode, value );
}


static void generate_expr_instr(// GENERATE EXPR-TYPE, INSTRUCTION
    PTREE expr,                 // - current node
    unsigned value,             // - value for ic instruction
    CGOP opcode )               // - opcode
{
    generate_node_type( expr );
    CgFrontCodeUint( opcode, value );
}


static SYMBOL getPtreeSymbol(   // PICK UP SYMBOL FROM PTREE NODE
    PTREE node )                // - the node
{
    SYMBOL sym;                 // - the symbol

    if( NULL == node ) {
        sym = NULL;
    } else {
        sym = node->u.symcg.symbol;
        if( sym != NULL ) {
            sym = SymDeAlias( sym );
        }
    }
    return sym;
}


static SYMBOL getLeftPtreeSymbol( // PICK UP SYMBOL FROM LEFT PTREE NODE
    PTREE node )                // - node at top
{
    return getPtreeSymbol( PTreeOpLeft( node ) );
}


static void generateRargOffset( // GENERATE BINDING FOR REFERENCE ARG., OFFSET
    PTREE arg,                  // - next call argument
    int arg_no,                 // - argument #
    unsigned offset )           // - offset
{
    CgFrontCodePtr( IC_RARG_SYM, getPtreeSymbol( arg ) );
    if( 0 != offset ) {
        CgFrontCodeInt( IC_RARG_OFFSET, offset );
    }
    CgFrontCodeInt( IC_RARG_FUNC, arg_no );
}


static void generateRarg(       // GENERATE BINDING FOR REFERENCE ARG.
    PTREE arg,                  // - next call argument
    int arg_no )                // - argument #
{
    generateRargOffset( arg, arg_no, 0 );
}


static void generateRargVbOffset( // GENERATE BINDING FOR VB-REF ARG., OFFSET
    PTREE arg,                  // - next call argument
    int arg_no,                 // - argument #
    unsigned offset )           // - offset
{
// Note: This optimization is enabled only when the symbol has exact type.
//       This is because the offset is calculated assuming that the item is
//       exact.
//       In the future, we could soup this up (like IC_VB_FETCH) when we
//       know, in the called routine, the exact type of the symbol which
//       is bound to this symbol.
//
//       The symbol does not have known exact type when it is an argument.
    SYMBOL sym = getPtreeSymbol( arg );
    if( NULL != sym
     && ! SymIsArgument( sym ) ) {
        CgFrontCodePtr( IC_RARG_SYM, sym );
//      CgFrontCodeInt( IC_RARG_VBOFFSET, offset );
        CgFrontCodeInt( IC_RARG_OFFSET, offset );
        CgFrontCodeInt( IC_RARG_FUNC, arg_no );
    }
}


static unsigned vbaseDelta(     // GET OFFSET FOR CO_VBASE_FETCH
    PTREE expr )                // - CO_VBASE_FETCH expression
{
    return PtdGetVbExact( expr );
}


static PTREE getChildNode(      // GET CHILD, REMOVE CASTING
    PTREE *a_src )              // - addr[ source ]
{
    PTREE retn;                 // - NULL or child node

    if( NULL == *a_src ) {
        retn = NULL;
    } else {
        retn = NodeRemoveCasts( PTreeOp( a_src ) );
    }
    return retn;
}


static void generateCallRefICs( // GENERATE IC'S FOR REFERENCE PARAMETERS
    PTREE expr )                // - call expression
{
    PTREE arg;                  // - next call argument
    PTREE right;                // - RHS of arg
    int arg_no;                 // - argument #
    unsigned off;               // - offset argument

    for( expr = expr->u.subtree[1], arg_no = 0
       ; expr != NULL
       ; expr = expr->u.subtree[0], ++arg_no ) {
        if( expr->flags & PTF_ARG_THIS
         || NULL != TypeReference( NodeType( expr ) ) ) {
            arg = getChildNode( &expr->u.subtree[1] );
            if( arg->op == PT_SYMBOL ) {
                generateRarg( arg, arg_no );
            } else if( NodeIsUnaryOp( arg, CO_RARG_FETCH ) ) {
                arg = getChildNode( &arg->u.subtree[0] );
                generateRarg( arg, arg_no );
            } else {
                if( NodeIsUnaryOp( arg, CO_INDIRECT ) ) {
                    arg = getChildNode( &arg->u.subtree[0] );
                }
                if( NodeIsBinaryOp( arg, CO_DOT ) ) {
                    INT_CONSTANT icon;
                    right = arg->u.subtree[1];
                    if( NodeIsIntConstant( right, &icon ) ) {
                        off = icon.uval;
                        arg = getChildNode( &arg->u.subtree[0] );
                        if( arg->op == PT_SYMBOL ) {
                            generateRargOffset( arg, arg_no, off );
                        } else if( NodeIsUnaryOp( arg, CO_RARG_FETCH ) ) {
                            arg = getChildNode( &arg->u.subtree[0] );
                            generateRargOffset( arg, arg_no, off );
                        } else if( NodeIsUnaryOp( arg, CO_VBASE_FETCH ) ) {
                            off += vbaseDelta( arg );
                            arg = getChildNode( &arg->u.subtree[0] );
                            generateRargVbOffset( arg, arg_no, off );
                        }
                    }
                } else if( NodeIsUnaryOp( arg, CO_VBASE_FETCH ) ) {
                    off = vbaseDelta( arg );
                    arg = getChildNode( &arg->u.subtree[0] );
                    generateRargVbOffset( arg, arg_no, off );
                }
            }
        }
    }
}


static TYPE generate_call_type( // GENERATE TYPE FOR CALL SETUP
    PTREE expr )                // - setup expression
{
    TYPE type;                  // - could be pointer to function, function
    TYPE pted;                  // - NULL or function type
    TYPE retn;                  // - return type
    TYPE unmd;                  // - unmodified function type

    type = expr->type;
    pted = TypePointedAtModified( type );
    if( pted != NULL ) {
        type = pted;
    }
    unmd = FunctionDeclarationType( type );
    retn = unmd->of;
    if( unmd->flag & TF1_PLUSPLUS ) {
        CgSetType( retn );
    } else {
        CgSetTypeExact( retn );
    }
    return type;
}


static SYMBOL getAliasDtorSym(  // GET ALIASED DTOR SYMBOL
    SYMBOL sym )                // - original symbol
{
    sym = SymDeAlias( sym );
    sym->flag |= SF_ADDR_TAKEN;
    return SymMarkRefed( sym );
}


static boolean emitAutoMarking( // EMIT MARKING FOR AN AUTO VAR
    SYMBOL sym )                // - the auto var
{
    boolean br = CgFrontRetnOptVar( sym );

⌨️ 快捷键说明

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