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 + -
显示快捷键?