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