cgbkcmds.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 736 行 · 第 1/2 页
C
736 行
/****************************************************************************
*
* 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 "cgback.h"
#include "cgbackut.h"
#include "typesig.h"
#include "ctexcept.h"
#include "carve.h"
#include "ring.h"
#include "initdefs.h"
#ifndef NDEBUG
#include "errdefns.h"
#include <stdio.h>
#include "dbg.h"
#include "toggle.h"
#include "pragdefn.h"
#endif
enum // INDICES FOR STATE-TABLE COMMANDS
{ DTOR_CMD_INDEX_VBASE // - virtual base
, DTOR_CMD_INDEX_DBASE // - direct base
, DTOR_CMD_INDEX_SETSV // - set sv (must be last)
};
static carve_t carveCMD_SET_SV; // allocations for CMD_SET_SV
static carve_t carveCMD_TEST_FLAG; // allocations for CMD_TEST_FLAG
static carve_t carveCMD_TRY; // allocations for CMD_TRY
static carve_t carveCMD_FN_EXC; // allocations for CMD_FN_EXC
static carve_t carveCMD_COMPONENT; // allocations for CMD_COMPONENT
static carve_t carveCMD_ARRAY_INIT; // allocations for CMD_ARRAY_INIT
static carve_t carveCMD_DEL_1; // allocations for CMD_DEL_1
static carve_t carveCMD_DEL_2; // allocations for CMD_DEL_2
static carve_t carveCMD_DEL_1_ARRAY; // allocations for CMD_DEL_1_ARRAY
static carve_t carveCMD_DEL_2_ARRAY; // allocations for CMD_DEL_2_ARRAY
static carve_t carveCMD_CTOR_TEST; // allocations for CMD_CTOR_TEST
static CMD_SET_SV* ringCmdsSetSv; // commands: SET_SV
static CMD_TEST_FLAG* ringCmdsTestFlag; // commands: TEST_FLAG
static CMD_COMPONENT* ringCmdsComponent;// commands: COMPONENT (function)
static CMD_TRY* ringCmdsTry; // commands: TRY
static CMD_FN_EXC* ringCmdsFnExc; // commands: FN_EXC
static CMD_DEL_1* ringCmdsDel1; // commands: DEL_1
static CMD_DEL_2* ringCmdsDel2; // commands: DEL_2
static CMD_DEL_1* ringCmdsDel1Array; // commands: DEL_1_ARRAY
static CMD_DEL_2* ringCmdsDel2Array; // commands: DEL_2_ARRAY
static CMD_ARRAY_INIT* ringCmdsArrayInit;//commands: array initialization
static CMD_CTOR_TEST* ringCmdsCtorTest; // commands: CTOR_TEST
static void* stateTableCmdAlloc(// ALLOCATE STATE-TABLE CMD
carve_t allocation, // - allocation
void** hdr ) // - ring hdr
{
CMD_BASE* cmd;
cmd = RingCarveAlloc( allocation, hdr );
cmd->emitted = FALSE;
cmd->sym = NULL;
return cmd;
}
static void* stateTableCmdAllocVar( // ALLOCATE STATE-TABLE CMD, SET VAR
carve_t allocation, // - allocation
void** hdr, // - ring hdr
target_size_t size ) // - size of command
{
CMD_BASE* cmd;
cmd = stateTableCmdAlloc( allocation, hdr );
cmd->sym = CgVarRo( size, SC_STATIC, NULL );
return cmd;
}
static SYMBOL stateTableCmdName(// CREATE COMDEF VARIABLE FOR DTOR_CMD
unsigned index ) // - command index
{
return CgVarRo( 1, SC_PUBLIC, CppNameStateTableCmd( index ) );
}
SYMBOL CgCmdFnExc( // GET SYMBOL FOR FN-EXCEPTION SPEC. COMMAND
SE* se ) // - state entry in state table
{
TYPE_SIG_ENT* sigs; // - ring of signatures
CMD_FN_EXC* cmd; // - command
sigs = BeTypeSigEntsCopy( se->fn_exc.sigs );
cmd = stateTableCmdAllocVar
( carveCMD_FN_EXC
, &ringCmdsFnExc
, 2 +
CgbkInfo.size_offset +
RingCount( sigs ) * CgbkInfo.size_data_ptr );
cmd->sigs = sigs;
return cmd->base.sym;
}
SYMBOL CgCmdTestFlag( // GET SYMBOL FOR TEST_FLAG CMD TO BE GEN'ED
SE* se ) // - state entry in state table
{
CMD_TEST_FLAG* cmd; // - command for entry
CMD_TEST_FLAG* curr; // - current command
STATE_VAR sv_true; // - true state
STATE_VAR sv_false; // - false state
cmd = NULL;
sv_true = SeStateVar( se->test_flag.se_true );
sv_false = SeStateVar( se->test_flag.se_false );
RingIterBeg( ringCmdsTestFlag, curr ) {//{
if( se->test_flag.index == curr->index
&& sv_true == curr->state_var_true
&& sv_false == curr->state_var_false ) {
cmd = curr;
break;
}
} RingIterEnd( curr )
if( cmd == NULL ) {
cmd = stateTableCmdAllocVar( carveCMD_TEST_FLAG
, &ringCmdsTestFlag
, 2 + 3 * CgbkInfo.size_offset );
cmd->index = se->test_flag.index;
cmd->state_var_true = sv_true;
cmd->state_var_false = sv_false;
}
return cmd->base.sym;
}
SYMBOL CgCmdSetSv( // GET SYMBOL FOR SET_SV CMD TO BE GEN'ED
SE* se ) // - state entry in state table
{
CMD_SET_SV* cmd; // - command for entry
CMD_SET_SV* curr; // - current command
STATE_VAR state; // - state for set_sv
cmd = NULL;
state = SeStateVar( se->set_sv.se );
RingIterBeg( ringCmdsSetSv, curr ) {
if( state == curr->state_var ) {
cmd = curr;
break;
}
} RingIterEnd( curr )
if( cmd == NULL ) {
cmd = stateTableCmdAlloc( carveCMD_SET_SV, &ringCmdsSetSv );
cmd->state_var = state;
cmd->base.sym = stateTableCmdName( state + DTOR_CMD_INDEX_SETSV );
}
return cmd->base.sym;
}
// note: the code disabled does not work because it checks offset; it should
// check the offset relative to the R/W block, because that it what
// is generated ultimately.
//
// fix in future by computing the relative offset and using it
//
//
SYMBOL CgCmdComponent( // GET SYMBOL FOR DTC_COMP... COMMAND
SE* se ) // - state entry in state table
{
CMD_COMPONENT* cmd; // - command
DbgVerify( UNDEF_AREL != se->component.obj->offset
, "CgCmdComponent -- no offset" );
cmd = stateTableCmdAllocVar( carveCMD_COMPONENT
, &ringCmdsComponent
, 1 );
cmd->obj = se->component.obj;
cmd->dtor = se->component.dtor;
cmd->offset = se->component.offset;
cmd->cmd_type = se->base.se_type;
return cmd->base.sym;
}
SYMBOL CgCmdArrayInit( // GET SYMBOL FOR DTC_ARRAY_INIT COMMAND
SE* se ) // - state entry in state table
{
CMD_ARRAY_INIT* cmd; // - command
DbgVerify( UNDEF_AREL != se->array_init.reg->offset
, "cgAddCmdArrayInit -- no offset" );
cmd = stateTableCmdAllocVar( carveCMD_ARRAY_INIT
, &ringCmdsArrayInit
, 1 );
cmd->reg = se->array_init.reg;
return cmd->base.sym;
}
SYMBOL CgCmdDel1( // GET SYMBOL FOR DTC_DEL_1
SE* se ) // - state entry in state table
{
CMD_DEL_1* cmd; // - command for operation
CMD_DEL_1* cur; // - current command
DbgVerify( UNDEF_AREL != se->del_1.offset
, "CgCmdDel1 -- no offset for DLT_1" );
cmd = NULL;
RingIterBeg( ringCmdsDel1, cur ) {
if( cur->op_del == se->del_1.op_del
&& cur->offset == se->del_1.offset ) {
cmd = cur;
break;
}
} RingIterEnd( cur )
if( cmd == NULL ) {
cmd = stateTableCmdAllocVar( carveCMD_DEL_1
, &ringCmdsDel1
, 1 );
cmd->op_del = se->del_1.op_del;
cmd->offset = CgOffsetRw( se->del_1.offset );
}
return cmd->base.sym;
}
SYMBOL CgCmdDel1Array( // GET SYMBOL FOR DTC_DEL_1
SE* se ) // - state entry in state table
{
CMD_DEL_1_ARRAY* cmd; // - command for operation
CMD_DEL_1_ARRAY* cur; // - current command
DbgVerify( UNDEF_AREL != se->del_1_array.offset
, "CgCmdDel1 -- no offset for DLT_1" );
cmd = NULL;
RingIterBeg( ringCmdsDel1Array, cur ) {
if( cur->op_del == se->del_1_array.op_del
&& cur->offset == se->del_1_array.offset ) {
cmd = cur;
break;
}
} RingIterEnd( cur )
if( cmd == NULL ) {
cmd = stateTableCmdAllocVar( carveCMD_DEL_1_ARRAY
, &ringCmdsDel1Array
, 1 );
cmd->op_del = se->del_1_array.op_del;
cmd->offset = CgOffsetRw( se->del_1_array.offset );
}
return cmd->base.sym;
}
SYMBOL CgCmdDel2( // GET SYMBOL FOR DTC_DEL_2
SE* se ) // - state entry in state table
{
CMD_DEL_2* cmd; // - command for operation
CMD_DEL_2* cur; // - current command
DbgVerify( UNDEF_AREL != se->del_2.offset
, "CgCmdDel2 -- no offset for DLT_2" );
cmd = NULL;
RingIterBeg( ringCmdsDel2, cur ) {
if( cur->op_del == se->del_2.op_del
&& cur->offset == se->del_2.offset
&& cur->size == se->del_2.size ) {
cmd = cur;
break;
}
} RingIterEnd( cur )
if( cmd == NULL ) {
cmd = stateTableCmdAllocVar( carveCMD_DEL_2
, &ringCmdsDel2
, 1 );
cmd->op_del = se->del_2.op_del;
cmd->offset = CgOffsetRw( se->del_2.offset );
cmd->size = se->del_2.size;
}
return cmd->base.sym;
}
SYMBOL CgCmdDel2Array( // GET SYMBOL FOR DTC_DEL_2
SE* se ) // - state entry in state table
{
CMD_DEL_2_ARRAY* cmd; // - command for operation
CMD_DEL_2_ARRAY* cur; // - current command
DbgVerify( UNDEF_AREL != se->del_2_array.offset
, "CgCmdDel2 -- no offset for DLT_2" );
cmd = NULL;
RingIterBeg( ringCmdsDel2Array, cur ) {
if( cur->op_del == se->del_2_array.op_del
&& cur->offset == se->del_2_array.offset
&& cur->size == se->del_2_array.size ) {
cmd = cur;
break;
}
} RingIterEnd( cur )
if( cmd == NULL ) {
cmd = stateTableCmdAllocVar( carveCMD_DEL_2_ARRAY
, &ringCmdsDel2Array
, 1 );
cmd->op_del = se->del_2_array.op_del;
cmd->offset = CgOffsetRw( se->del_2_array.offset );
cmd->size = se->del_2_array.size;
}
return cmd->base.sym;
}
SYMBOL CgCmdTry( // GET SYMBOL FOR TRY BLOCK
SE* se ) // - state entry in state table
{
TYPE_SIG_ENT* sigs; // - ring of type signatures
CMD_TRY* cmd; // - command
DbgVerify( UNDEF_AREL != se->try_blk.try_impl->offset_jmpbuf
, "cgGenerateCmdsTry -- no offset for jmpbuf" );
DbgVerify( UNDEF_AREL != se->try_blk.try_impl->offset_var
, "cgGenerateCmdsTry -- no offset for var" );
sigs = BeTypeSigEntsCopy( se->try_blk.sigs );
cmd = stateTableCmdAllocVar
( carveCMD_TRY
, &ringCmdsTry
, 2 + 2 +
3 * CgbkInfo.size_offset +
RingCount( sigs ) * CgbkInfo.size_data_ptr );
cmd->state = SeStateVar( FstabPrevious( se ) );
cmd->offset_var = CgOffsetRw( se->try_blk.try_impl->offset_var );
cmd->offset_jmpbuf = CgOffsetRw( se->try_blk.try_impl->offset_jmpbuf );
cmd->sigs = sigs;
return cmd->base.sym;
}
SYMBOL CgCmdCtorTest( // GET SYMBOL FOR CTOR-TEST COMMAND
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?