cgbkutil.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,074 行 · 第 1/3 页

C
1,074
字号
/****************************************************************************
*
*                            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 "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "cgaux.h"
#include "cginfo.h"
#include "rtfuncod.h"
#include "cgbackut.h"
#include "objmodel.h"
#include "cgio.h"

#ifndef NDEBUG
    #include "errdefns.h"
    #include "pragdefn.h"
#endif


//***********************************************************************
// Data Generation Support
//***********************************************************************


// This routine must be called to correspond to the AlignPad... macros in
// RTEXCEPT.H and CPPLIB.H
//
void DgAlignPad(                // INSERT PADDING IN A STRUCTURE
    unsigned total )            // - number of bytes emitted so far
{
    unsigned left;

#if ( _CPU == _AXP ) || ( _CPU == 386 )
    #define ALIGN 4
#else
    #define ALIGN 2
#endif

    left = ( ( total + ALIGN - 1 ) & ( - ALIGN ) ) - total;
    if( left > 0 ) {
        DgUninitBytes( left );
    }
#undef ALIGN
}


static void alignInSegment(     // PUT OUT ALIGNMENT WITHIN A SEGMENT
    target_size_t adjust,       // - adjustment
    fe_seg_id segid )           // - segment id
{
    if( adjust > 0 ) {
        if( segid == SEG_BSS ) {
            DgUninitBytes( adjust );
        } else {
            DgInitBytes( adjust, 0 );
        }
    }
}


void DgAlignSymbol(             // ALIGN SYMBOL TO CORRECT BOUNDARY
    SYMBOL sym )                // - symbol to align
{
    target_size_t adjust;
    fe_seg_id segid;

    segid = sym->segid;
    adjust = SegmentAdjust( segid, DGTell(), SegmentAlignment( sym ) );
    alignInSegment( adjust, segid );
}


#if _CPU == _AXP
void DgAlignInternal(           // ALIGN INTERNAL CONTROL BLOCK
    void )
{
    target_size_t adjust;

    adjust = SegmentAdjust( SEG_CONST, DGTell(), TARGET_POINTER );
    alignInSegment( adjust, SEG_CONST );
}
#endif


void DgUninitBytes(             // DATA GENERATE UNINIT BYTES
    target_size_t size )        // - number of bytes
{
    if( size == TARGET_UINT_MAX+1 ) {
        size /= 2;
        DGUBytes( size );
        DGUBytes( size );
    } else {
        DGUBytes( size );
    }
}


void DgInitBytes(               // DATA GENERATE INIT BYTES
    target_size_t   size,       // - number of bytes
    uint_8          val )       // - byte to initialize with
{
    if( size == TARGET_UINT_MAX+1 ) {
        size /= 2;
        DGIBytes( size, val );
        DGIBytes( size, val );
    } else {
        DGIBytes( size, val );
    }
}


void DgByte(                    // DATA GENERATE A BYTE
    uint_8 byte )               // - to be generated
{
#if 0
    DGBytes( 1, &byte );
#else
    DGInteger( byte, T_UINT_1 );
#endif
}


void DgSymbolDefInit(           // DATA GENERATE SYMBOL (DEFAULT DATA)
    SYMBOL sym )                // - the symbol
{
    segment_id      old_id;     // - old segment
    segment_id      seg_id;     // - symbol segment
    target_size_t   size;       // - size of symbol

    seg_id = FESegID( sym );
    old_id = BESetSeg( seg_id );
    DgAlignSymbol( sym );
    DGLabel( FEBack( sym ) );
    size = CgMemorySize( sym->sym_type );
    if( sym->segid == SEG_BSS ) {
        DgUninitBytes( size );
    } else {
        DgInitBytes( size, 0 );
    }
    BESetSeg( old_id );
}


static void dataGenPtrSym(      // GENERATE POINTER FOR A SYMBOL + OFFSET
    SYMBOL sym,                 // - the symbol
    target_size_t offset,       // - the offset
    cg_type type )              // - codegen type of pointer
{
    if( sym == NULL ) {
        DbgVerify( offset == 0
                 , "dataGenPtrSym -- NULL symbol with offset <> 0" );
        DGInteger( 0, type );
    } else {
        DGFEPtr( (cg_sym_handle)sym, type, offset );
        if( type == T_CODE_PTR
         && SymIsThunk( sym ) ) {
            CgioThunkAddrTaken( sym );
        }
    }
}


void DgPtrSymOff(               // GENERATE POINTER FOR A SYMBOL + OFFSET
    SYMBOL sym,                 // - the symbol
    target_size_t offset )      // - the offset
{
    if( sym == NULL || SymIsFunction( sym ) ) {
        DbgVerify( offset == 0
                 , "DgPtrSymOffset -- function with offset <> 0" );
        dataGenPtrSym( NULL, offset, T_CODE_PTR );
    } else {
        dataGenPtrSym( sym, offset, T_POINTER );
    }
}


void DgOffset(                  // GENERATE AN OFFSET VALUE
    unsigned offset )           // - offset value
{
    DGInteger( offset, CgTypeOffset() );
}


void DgPtrSymDataOffset(        // GENERATE POINTER FOR A DATA SYMBOL, OFFSET
    SYMBOL sym,                 // - the symbol
    target_size_t offset )      // - the offset
{
    dataGenPtrSym( sym, offset, T_POINTER );
}


void DgPtrSymData(              // GENERATE POINTER FOR A DATA SYMBOL
    SYMBOL sym )                // - the symbol
{
    DgPtrSymDataOffset( sym, 0 );
}


void DgPtrSymCode(              // GENERATE POINTER FOR A CODE SYMBOL
    SYMBOL sym )                // - the symbol
{
    dataGenPtrSym( sym, 0, T_CODE_PTR );
}


fe_seg_id CgBackGenLabel(       // GENERATE A LABEL
    SYMBOL sym )                // - symbol defining label
{
    segment_id      old_id;     // - old segment
    segment_id      seg_id;     // - new segment

    seg_id = FESegID( sym );
    old_id = BESetSeg( seg_id );
    DGLabel( FEBack( sym ) );
    return old_id;
}


fe_seg_id CgBackGenLabelInternal(// GENERATE A LABEL FOR INTERNAL STRUCTURE
    SYMBOL sym )                // - symbol defining label
{
    segment_id      old_id;     // - old segment
    segment_id      seg_id;     // - new segment

    seg_id = FESegID( sym );
    old_id = BESetSeg( seg_id );
    DgAlignInternal();
    DGLabel( FEBack( sym ) );
    return old_id;
}

static fe_seg_id dgCurrSeg( void )
{
    fe_seg_id curr_seg;

    curr_seg = BESetSeg( SEG_CONST );
    BESetSeg( curr_seg );
    return( curr_seg );
}

back_handle DgStringConst(          // STORE STRING CONSTANT WITH NULL
    STRING_CONSTANT str,            // - string to store
    uint_16         *psegid,        // - addr(string segid)
    unsigned        control )       // - control mask (DSC_*)
{
    back_handle     handle;         // - back handle for literal
    target_offset_t str_align;      // - string's alignment
    target_size_t   str_len;        // - string's length (in bytes)
    segment_id      str_seg;        // - string's segment
    segment_id      old_seg;        // - old segment

    str_seg = str->segid;
    handle = str->cg_handle;
    if( control & DSC_CONST ) {
        if( handle == 0 ) {
            handle = (void *)BENewBack( NULL );
            str->cg_handle = handle;
            str_len = str->len + TARGET_CHAR;
            if( str->wide_string ) {
                str_align = TARGET_WIDE_CHAR;
            } else {
                str_align = TARGET_CHAR;
            }
#if _CPU == _AXP
            str_seg = SEG_CONST;
#else
            if( CompFlags.strings_in_code_segment && ( control & DSC_CODE_OK ) != 0 ) {
                if( IsBigData() ) {
                    str_seg = SegmentAddStringCodeFar( str_len, str_align );
                } else {
                    if( TargetSwitches & FLAT_MODEL ) {
                        str_seg = SegmentAddStringCodeFar( str_len, str_align );
                    } else {
                        str_seg = SEG_CONST;
                    }
                }
            } else {
                if( IsBigData() ) {
                    str_seg = SegmentAddStringConstFar( str_len, str_align );
                } else {
                    str_seg = SEG_CONST;
                }
            }
#endif
            str->segid = str_seg;
            old_seg = BESetSeg( str_seg );
#if _CPU == _AXP
            DGAlign( TARGET_INT );
#else
            DGAlign( str_align );   // NT requires word aligned wide strings
#endif
            DGLabel( handle );
            DGString( str->string, str->len );
            DgByte( 0 );
#if _CPU == _AXP
            DGAlign( TARGET_INT );
#endif
            BESetSeg( old_seg );
        }
    } else {
        // char a[] = "asdf"; initialization (use current segment)
        str_seg = dgCurrSeg();
        str->segid = str_seg;
        DGString( str->string, str->len );
        DgByte( 0 );
    }
    if( psegid != NULL ) {
        *psegid = str_seg;
    }
    return( handle );
}



//***********************************************************************
// Destruction Methods
//***********************************************************************


DT_METHOD DtmDirect(            // CONVERT DTOR METHOD TO DIRECT COUNTERPART
    DT_METHOD dtm )             // - default method
{
    switch( dtm ) {
      DbgDefault( "DtmDirect -- bad method" );
      case DTM_DIRECT :
      case DTM_DIRECT_SMALL :
        break;
      case DTM_TABLE_SMALL :

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?