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