cgbkmain.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,832 行 · 第 1/5 页
C
1,832 行
/****************************************************************************
*
* 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: Back-end control for C++.
*
****************************************************************************/
#include "plusplus.h"
#include <float.h>
#include "cgfront.h"
#include "cgback.h"
#include "memmgr.h"
#include "errdefns.h"
#include "codegen.h"
#include "cgbackut.h"
#include "cgaux.h"
#include "cginfo.h"
#include "ring.h"
#include "conpool.h"
#include "stringl.h"
#include "rtfuncod.h"
#include "carve.h"
#include "label.h"
#include "vstk.h"
#include "context.h"
#include "name.h"
#include "ctexcept.h"
#include "symdbg.h"
#include "dwarfdbg.h"
#include "callgrph.h"
#include "cdopt.h"
#include "initdefs.h"
#include "stats.h"
#include "specfuns.h"
#include "objmodel.h"
#include "extrf.h"
#include "fmtsym.h"
#include "floatsup.h"
#include "rtti.h"
#ifndef NDEBUG
#include "pragdefn.h"
#endif
#define ST_backwards_beg( h, i ) \
{ \
SE* __HDR = h; \
SE* __PRV = NULL; \
for( i = __HDR; __PRV != __HDR; i = __PRV ) { \
__PRV = i->base.prev;
#define ST_backwards_end \
} \
}
#define ST_backwards_prev( p ) \
__PRV = p
#define ST_backwards_setsv( s ) \
__PRV = (s)->set_sv.se; \
if( __PRV == NULL ) { \
__PRV = __HDR; \
}
#define IC_PARM_STACK_SIZE (16)
#define IC_PARM_PUSH_PTR( p ) \
DbgAssert( ic_sp < IC_PARM_STACK_SIZE ); \
ic_parms[ic_sp++].pvalue = p;
#define IC_PARM_PUSH_INT( i ) \
DbgAssert( ic_sp < IC_PARM_STACK_SIZE ); \
ic_parms[ic_sp++].ivalue = i;
#define IC_PARM_POP_PTR( p ) \
DbgAssert( ic_sp != 0 ); \
p = ic_parms[--ic_sp].pvalue;
#define IC_PARM_POP_INT( i ) \
DbgAssert( ic_sp != 0 ); \
i = ic_parms[--ic_sp].ivalue;
#define IC_PARM_DONE \
DbgAssert( ic_sp == 0 ); \
ic_sp = 0;
#ifndef NDEBUG
#include <stdio.h>
#include "dbg.h"
#define dump_label( ins ) if( PragDbgToggle.dump_labels ) ins
#else
#define dump_label( ins )
#endif
#define TY_VOID TY_INTEGER
static VSTK_CTL stack_labs_cs; // stack: labels (control)
static VSTK_CTL stack_goto_near; // stack: gotos (near)
static unsigned max_inline_depth; // maximum depth of inlining
static unsigned depth_inline; // depth of inlining
static SYMBOL statics; // static symbols (freed at file end)
static SYMBOL autos; // automatic variables for procedure
static carve_t carveTRY_IMPL; // allocations for TRY_IMPL
static carve_t carveSTAB_OBJ; // allocations for STAB_OBJ
static SCOPE scope_exit; // scope exited by IC_SCOPE_EXIT
static CGFILE *data_file; // data file
static STAB_OBJ* state_tables_obj; // state tables for objects
static boolean sig_thunk_genned; // TRUE ==> significant thunk genned
static SYMBOL thisSym; // model for 'this' symbol
static SYMBOL cdtorSym; // model for cdtor extra parm
static TRY_IMPL* fun_try_impls; // function try implementations
// static SYMBOL new_ctor_ptr; // contains ptr to new'ed area
ExtraRptCtr( ctr_ic_codes ); // number of IC codes
ExtraRptCtr( ctr_inlines ); // number of inlines
ExtraRptCtr( ctr_funcs ); // number of functions
CGBK_INFO CgbkInfo; // useful information
static void cgResetThis( // RESET THIS, IF REQUIRED
target_offset_t offset ) // - offset of object just CTOR'ed/DTOR'ed
{
SYMBOL sym; // - symbol for " this"
SYMBOL ref; // - not used: bound reference
target_offset_t offset_ref; // - not used: offset from bound reference
cg_name expr; // - expression
if( ! IbpReference( NULL, &sym, &ref, &offset_ref ) ) {
expr = CgExprPop();
if( offset > 0 ) {
expr = CGBinary( O_MINUS, expr, CgOffset( offset ), T_POINTER );
}
expr = CGLVAssign( CgSymbol( sym ), expr, T_POINTER );
CgExprPush( expr, T_POINTER );
}
}
unsigned CgNonThunkDepth( // COMPUTE INLINE DEPTH WITHOUT THUNKS
FN_CTL* fctl ) // - current function
{
unsigned real_depth; // - depth without inlines
real_depth = depth_inline;
if( real_depth > 0 ) {
for( ; ; ) {
fctl = FnCtlPrev( fctl );
if( fctl == NULL ) break;
if( SymIsThunk( fctl->func ) ) {
-- real_depth;
}
}
}
return real_depth;
}
#if 0
static void push_optional_expr( // PUSH EXPRESSION IF NOT EMPTY
cg_name expr, // - NULL or expression
cg_type type ) // - type, when non-null
{
if( expr != NULL ) {
CgExprPush( expr, type );
}
}
#endif
#if 0
static void push_reqd_expr( // PUSH REQUIRED EXPRESSION ON STACK
cg_name expr, // - expression to be pushed
cg_type type ) // - type
{
if( expr == NULL ) {
CgPushGarbage();
} else {
CgExprPush( expr, type );
}
}
#endif
static TRY_IMPL* tryImpl( // FIND/ALLOCATE A TRY IMPLEMENTATION
SYMBOL sym ) // - try variable
{
#if _CPU == _AXP
#define JMPBUF_SIZE ( 24 * TARGET_DOUBLE )
#elif _INTEL_CPU
#define JMPBUF_SIZE ( 13 * TARGET_INT )
#else
#error bad target
#endif
TRY_IMPL* try_impl; // - try implementation
TRY_IMPL* curr; // - current try implementation
sym = SymTrans( sym );
try_impl = NULL;
RingIterBeg( fun_try_impls, curr ) {
if( curr->try_sym == sym ) {
try_impl = curr;
break;
}
} RingIterEnd( curr )
if( try_impl == NULL ) {
try_impl = RingCarveAlloc( carveTRY_IMPL, &fun_try_impls );
try_impl->try_sym = sym;
AutoRelRegister( try_impl->try_sym, &try_impl->offset_var );
try_impl->jmp_sym = CgVarRw( JMPBUF_SIZE, SC_AUTO );
AutoRelRegister( try_impl->jmp_sym, &try_impl->offset_jmpbuf );
}
return try_impl;
}
static void freeTryImpls( // FREE TRY IMPLEMENTATIONS
void )
{
RingCarveFree( carveTRY_IMPL, &fun_try_impls );
}
static SE* stateTableTryBlk( // GET CURRENT STATE TABLE TRY BLOCK
TRY_IMPL* try_impl ) // - try implementation
{
SE* try_blk; // - last try block
SE* curr; // - current state entry
try_blk = NULL;
ST_backwards_beg( FstabActualPosn(), curr ) {
if( ( curr->base.se_type == DTC_TRY )
&&( curr->try_blk.try_impl == try_impl ) ) {
try_blk = curr;
break;
}
} ST_backwards_end
DbgVerify( try_blk != NULL, "stateTableTryBlk -- none" );
return try_blk;
}
static void undefine_string_const( // UN-DEFINE A STRING CONSTANT
STRING_CONSTANT str ) // - the constant
{
if( str->cg_handle != NULL ) {
BEFreeBack( (back_handle)str->cg_handle );
str->cg_handle = NULL;
}
}
static SYMBOL transThisSym( // TRANSLATE TO "this_sym" WHEN NULL
SYMBOL sym, // - input symbol
FN_CTL *fctl ) // - current function control pointer
{
if( sym == NULL
&& ! SymIsStatic( fctl->func ) ) {
sym = fctl->this_sym;
}
return sym;
}
static void funcDebugInfo( // DEFINE FUNCTION DEBUGGING INFORMATION
FN_CTL *fctl ) // - current function control pointer
{
if( fctl->debug_info && ( GenSwitches & DBG_LOCALS ) ){
if( SymIsClassMember( fctl->func ) ) {
SYMBOL this_sym;
this_sym = transThisSym( NULL, fctl );
if( GenSwitches & DBG_DF ){
DwarfDebugMemberFunc( fctl->func, this_sym );
}else{
SymbolicDebugMemberFunc( fctl->func, this_sym );
}
}else if( SymIsNameSpaceMember( fctl->func ) ){
if( GenSwitches & DBG_DF ){
DwarfDebugNameSpaceEnclosed( fctl->func );
}
}
}
}
#define flushOverInitialization( __fc ) \
CgioReadICUntilOpcode( __fc, IC_INIT_DONE )
static SYMBOL finalAlias( // CHECK FOR ANONYMOUS UNION ALIASING
SYMBOL sym ) // - the symbol
{
SYMBOL check;
check = SymIsAnonymous( sym );
if( check != NULL ) {
sym = check;
}
return( sym );
}
static void cgDtorThisOffset( // DESTRUCT (*this)+offset
FN_CTL* fctl, // - file information
SYMBOL dtor, // - DTOR to be used
target_offset_t offset, // - offset
unsigned cdtor ) // - CDTOR value to be used
{
SYMBOL this_sym; // - symbol for "this"
SYMBOL refd_sym; // - symbol bound to "this"
target_offset_t refd_off; // - offset from "refd_sym"
cg_name expr; // - generated expression
if( IbpReference( NULL, &this_sym, &refd_sym, &refd_off ) ) {
CgDone( CgDestructSymOffset( fctl
, dtor
, refd_sym
, offset + refd_off
, cdtor )
, T_POINTER );
} else {
expr = CgFetchSymbolAddOffset( this_sym, offset );
expr = CgDestructExpr( dtor, expr, cdtor );
CgExprPush( expr, T_POINTER );
cgResetThis( offset );
CgDone( CgExprPop(), T_POINTER );
}
}
static void emitDtorComponent( // EMIT CODE TO DESTRUCT COMPONENT
FN_CTL* fctl, // - file information
SE* se, // - component entry
unsigned cdtor ) // - CDTOR parameter
{
if( ! fctl->ctor_complete ) {
FstabSetDtorState( se, fctl );
cgDtorThisOffset( fctl
, se->component.dtor
, se->component.offset
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?