datainit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,028 行 · 第 1/5 页
C
2,028 行
/****************************************************************************
*
* 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 <limits.h>
#include "errdefns.h"
#include "fnbody.h"
#include "cgfront.h"
#include "cgsegid.h"
#include "stringl.h"
#include "ptree.h"
#include "memmgr.h"
#include "ring.h"
#include "stack.h"
#include "carve.h"
#include "toggle.h"
#include "decl.h"
#include "dbg.h"
#include "datainit.h"
#include "rtfuncod.h"
#include "label.h"
#include "typesig.h"
#include "datadtor.h"
#include "initdefs.h"
#ifndef NDEBUG
#include "pragdefn.h"
#endif
#define BLOCK_NEST 16
#define BLOCK_QUEUE 16
#define OPEN_BRACE "{"
#define CLOSE_BRACE "}"
static carve_t carveQUEUE;
static carve_t carveNEST;
static INITIALIZE_DATA *currInit;
static unsigned runTimeThreshold = 1;
static unsigned long bitMask[] = { // for bitfields
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};
#ifdef NDEBUG
#define _fatal( x )
#define _dump( x )
#define _dumpPTree( x )
#define _dumpSymbol( x )
#define _dumpFullType( x )
#define _dumpInt( x, y )
#define _dumpPtr( x, y )
#define _dumpInitInfo( x )
#define _dumpDtorPtr( x, y )
#define _dumpDtorInt( x, y )
#define _dumpDtor( x )
#define _dumpDtorSymbol( x )
#else
#define __DUMP_INIT ( PragDbgToggle.dump_init )
#define __DUMP_DTOR ( __DUMP_INIT || ( PragDbgToggle.dump_data_dtor ) )
#define _fatal( x ) CFatal( x )
#define _dump( x ) if( __DUMP_INIT ) puts( x )
#define _dumpPTree( x ) if( __DUMP_INIT ) DumpPTree( x )
#define _dumpSymbol( x ) if( __DUMP_INIT ) DumpSymbol( x )
#define _dumpFullType( x ) if( __DUMP_INIT ) DumpFullType( x )
#define _dumpInt( x, y ) if( __DUMP_INIT ) printf( x, y )
#define _dumpInitInfo( x ) if( __DUMP_INIT ) DumpInitInfo( (void *) x )
#define _dumpDtorPtr( x, y ) if( __DUMP_DTOR ) printf( x, y )
#define _dumpDtorInt( x, y ) if( __DUMP_DTOR ) printf( x, y )
#define _dumpDtor( x ) if( __DUMP_DTOR ) puts( x )
#define _dumpDtorSymbol( x ) if( __DUMP_DTOR ) DumpSymbol( x )
#endif
#if 0
static void *dataInitCodeFileOpen( boolean modified, SCOPE *save )
/****************************************************************/
{
void *handle;
*save = NULL;
switch( currInit->location ) {
case DL_INTERNAL_STATIC:
handle = NULL;
if( modified && currInit->dtor_reqd ) {
CgFrontModInitUsed();
}
break;
case DL_EXTERNAL_STATIC:
case DL_EXTERNAL_PUBLIC:
handle = CgFrontModInitOpen( save );
if( modified ) {
CgFrontModInitUsed();
}
break;
}
return( handle );
}
static void dataInitCodeFileClose( void *handle, SCOPE save_scope )
/*****************************************************************/
{
switch( currInit->location ) {
case DL_EXTERNAL_STATIC:
case DL_EXTERNAL_PUBLIC:
CgFrontModInitClose( save_scope, handle );
break;
}
}
#else
// data for code file processing
static SCOPE code_file_save_scope; // saved scope
static void* code_file_save_handle; // handle for saved file
static int code_file_save_depth; // depth of open's
#define CODE_FILE_NOT_OPEN -1 // indicates code file not opened
static int code_file_open_depth; // depth of actual open (-1 ==> none)
static void dataInitCodeFileOpen( boolean modified )
/**************************************************/
{
switch( currInit->location ) {
#if 0
//JWW -- I think this is hysterically here from the time when we used
// the bit implementation of destruction
case DL_INTERNAL_STATIC:
if( modified && currInit->dtor_reqd ) {
CgFrontModInitUsed();
}
break;
#endif
case DL_EXTERNAL_STATIC:
case DL_EXTERNAL_PUBLIC:
if( CODE_FILE_NOT_OPEN == code_file_open_depth ) {
code_file_save_handle
= CgFrontModInitOpen( &code_file_save_scope );
code_file_open_depth = code_file_save_depth;
}
if( modified ) {
CgFrontModInitUsed();
}
break;
}
++code_file_save_depth;
}
static void dataInitCodeFileClose( void )
/***************************************/
{
DbgVerify( 0 != code_file_save_depth, "dataInitCodeFileClose -- bad depth" );
--code_file_save_depth;
if( code_file_save_depth == code_file_open_depth ) {
code_file_open_depth = CODE_FILE_NOT_OPEN;
CgFrontModInitClose( code_file_save_scope, code_file_save_handle );
}
}
#endif
static boolean isDataInitConstant( PTREE tree
, PTREE *ctree
, target_size_t *offset )
/********************************************************/
// return TRUE when it is a constant
{
PTREE right_tree;
// skip CO_EXPR_DONE
tree = PTreeOpLeft( tree );
if( tree->cgop != CO_INIT ) {
return( FALSE );
}
right_tree = tree->u.subtree[1];
// handle "int a = ( b=1, 2 );"
if( right_tree->flags & PTF_SIDE_EFF ) {
return( FALSE );
}
return( IsLinkerConstant( right_tree, ctree, offset ) );
}
static SYMBOL dtorableObjectInitSymbol( // SYMBOL FOR CURRENT DTORABLE OBJECT
void )
{
return currInit->auto_static ? currInit->auto_sym : currInit->sym;
}
static PTREE makeSafeSymbol( SYMBOL sym, TOKEN_LOCN *locn, SEARCH_RESULT *result )
{
PTREE tree;
tree = PTreeIdSym( sym );
tree = PTreeSetLocn( tree, locn );
tree = NodeSymbol( tree, sym, result );
return( tree );
}
static PTREE dataInitLeftSide( INITIALIZE_INFO *entry, TOKEN_LOCN* locn )
/***********************************************************************/
// recursive function to build left side of init expression
{
SYMBOL sym;
PTREE tree;
PTREE subtree;
tree = NULL;
if( entry->previous != NULL ) {
tree = dataInitLeftSide( entry->previous, locn );
}
if( entry->entry == DE_ROOT_TYPE ) {
tree = makeSafeSymbol( dtorableObjectInitSymbol(), locn, NULL );
} else if( currInit->nest != entry ) {
switch( entry->target ) {
case DT_ARRAY:
subtree = PTreeIntConstant( entry->u.a.index, TYP_UINT );
subtree = PTreeSetLocn( subtree, locn );
tree = PTreeBinary( CO_INDEX, tree, subtree );
tree = PTreeSetLocn( tree, locn );
break;
case DT_CLASS:
sym = entry->u.c.curr;
subtree = makeSafeSymbol( sym, locn, ScopeFindSymbol( sym ) );
tree = PTreeBinary( CO_DOT, tree, subtree );
tree = PTreeSetLocn( tree, locn );
break;
case DT_BITFIELD:
case DT_SCALAR:
case DT_ERROR:
break;
}
}
return( tree );
}
static PTREE dataInitPadLeftSide( target_size_t start )
/*****************************************************/
{
TYPE type;
PTREE tree;
tree = MakeNodeSymbol( dtorableObjectInitSymbol() );
type = tree->type;
tree = PTreeBinary( CO_DOT, tree, PTreeIntConstant( start, TYP_UINT ) );
type = TypeMergeForMember( type, currInit->base_type );
tree->type = type;
tree->flags |= PTF_LVALUE;
tree = NodeUnary( CO_INDIRECT, tree );
tree->type = type;
tree->flags |= PTF_LVALUE;
return( tree );
}
#if 0
static PTREE refOfSym( TYPE type, SYMBOL var )
/********************************************/
{
return NodeConvert( MakeReferenceTo( type ), MakeNodeSymbol( var ) );
}
#endif
static void dataInitEmitAutoAssign( SYMBOL dst, SYMBOL src )
/**********************************************************/
{
#if 0
TYPE type;
PTREE node;
target_size_t size;
#endif
currInit->emit_code = 1;
#if 0
size = currInit->nest->padded_size;
type = MakeArrayType( size );
if( size == 0 ) {
currInit->auto_type = type;
}
#endif
CgFrontCodePtr( IC_PARM_SYM, src );
CgFrontCodePtr( IC_INIT_AUTO, dst );
#if 0
type = MakeTypeOf( type, GetBasicType( TYP_UCHAR ) );
node = NodeFetch( refOfSym( type, src ) );
node = NodeAssign( refOfSym( type, dst ), node );
node = NodeDone( node );
_dump( "- Auto Assign Expression ------------------------------" );
_dumpPTree( node );
_dump( "-------------------------------------------------------" );
IcEmitExpr( node );
#endif
}
static void dataInitLabel( void )
/*******************************/
{
if( !currInit->label_done ) {
currInit->label_done = 1;
DgSymbolLabel( currInit->sym );
}
}
static void dataInitCheckHugeSegment( target_size_t position )
/************************************************************/
{
target_size_t check;
check = position % (TARGET_UINT_MAX+1);
if( position > 0 && check == 0 ) {
DgSegmentIncrement();
}
}
static boolean dataInitCheckHugeAlign( TYPE type )
/************************************************/
// returns TRUE if cannot align to segment
{
target_size_t total_size;
target_size_t base_size;
TYPE base_type;
total_size = CgMemorySize( type );
// The following is meaningless when TARGET_UINT_MAX == UINT_MAX
// (but this code will only ever get called for i86 target)
#if _CPU == 8086
if( total_size <= (TARGET_UINT_MAX+1) ) {
return( FALSE );
}
#endif
base_type = ArrayType( type );
while( base_type != NULL ) {
type = base_type->of;
base_type = ArrayType( type );
}
base_size = CgMemorySize( type );
return( (TARGET_UINT_MAX+1) % base_size );
}
static TYPE dtorableObjectType( // GET TYPE OF DTORABLE OBJECT (AT ROOT) ELEMENT
INITIALIZE_INFO* info ) // - info on current entry
{
TYPE type; // - NULL or type of dtorable element
if( info == NULL ) {
type = NULL;
} else if( info->entry == DE_ROOT_TYPE || info->entry == DE_TYPE ) {
if( TypeRequiresDtoring( info->type ) ) {
type = info->type;
} else {
type = NULL;
}
} else {
type = NULL;
}
return type;
}
static void emitDtorInitSymbol( // EMIT DTOR MARKING FOR A SYMBOL
void )
{
SYMBOL sym; // - symbol to be initialized
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?